Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17613
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace System.Web.Http.Properties {
using System;
using System.Linq;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class CommonWebApiResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal CommonWebApiResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
// Find the CommonResources.resources file's full resource name in this assembly
string commonResourcesName = global::System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames().Where(s => s.EndsWith("CommonWebApiResources.resources", StringComparison.OrdinalIgnoreCase)).Single();
// Trim off the ".resources"
commonResourcesName = commonResourcesName.Substring(0, commonResourcesName.Length - 10);
// Load the resource manager
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(commonResourcesName, typeof(CommonWebApiResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Relative URI values are not supported: &apos;{0}&apos;. The URI must be absolute..
/// </summary>
internal static string ArgumentInvalidAbsoluteUri {
get {
return ResourceManager.GetString("ArgumentInvalidAbsoluteUri", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unsupported URI scheme: &apos;{0}&apos;. The URI scheme must be either &apos;{1}&apos; or &apos;{2}&apos;..
/// </summary>
internal static string ArgumentInvalidHttpUriScheme {
get {
return ResourceManager.GetString("ArgumentInvalidHttpUriScheme", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Value must be greater than or equal to {0}..
/// </summary>
internal static string ArgumentMustBeGreaterThanOrEqualTo {
get {
return ResourceManager.GetString("ArgumentMustBeGreaterThanOrEqualTo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Value must be less than or equal to {0}..
/// </summary>
internal static string ArgumentMustBeLessThanOrEqualTo {
get {
return ResourceManager.GetString("ArgumentMustBeLessThanOrEqualTo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The argument &apos;{0}&apos; is null or empty..
/// </summary>
internal static string ArgumentNullOrEmpty {
get {
return ResourceManager.GetString("ArgumentNullOrEmpty", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to URI must not contain a query component or a fragment identifier..
/// </summary>
internal static string ArgumentUriHasQueryOrFragment {
get {
return ResourceManager.GetString("ArgumentUriHasQueryOrFragment", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The &apos;{0}&apos; must contain an item named &apos;{1}&apos; with a value of type &apos;{2}&apos;..
/// </summary>
internal static string DictionaryMissingRequiredValue {
get {
return ResourceManager.GetString("DictionaryMissingRequiredValue", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ArgumentInvalidAbsoluteUri" xml:space="preserve">
<value>Relative URI values are not supported: '{0}'. The URI must be absolute.</value>
</data>
<data name="ArgumentInvalidHttpUriScheme" xml:space="preserve">
<value>Unsupported URI scheme: '{0}'. The URI scheme must be either '{1}' or '{2}'.</value>
</data>
<data name="ArgumentMustBeGreaterThanOrEqualTo" xml:space="preserve">
<value>Value must be greater than or equal to {0}.</value>
</data>
<data name="ArgumentMustBeLessThanOrEqualTo" xml:space="preserve">
<value>Value must be less than or equal to {0}.</value>
</data>
<data name="ArgumentNullOrEmpty" xml:space="preserve">
<value>The argument '{0}' is null or empty.</value>
</data>
<data name="ArgumentUriHasQueryOrFragment" xml:space="preserve">
<value>URI must not contain a query component or a fragment identifier.</value>
</data>
<data name="DictionaryMissingRequiredValue" xml:space="preserve">
<value>The '{0}' must contain an item named '{1}' with a value of type '{2}'.</value>
</data>
</root>

View File

@@ -0,0 +1,149 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Web.Http.Properties;
namespace System.Web.Http
{
/// <summary>
/// Extension methods for <see cref="IDictionary{TKey,TValue}"/>.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
internal static class DictionaryExtensions
{
/// <summary>
/// Gets the value of <typeparamref name="T"/> associated with the specified key or <c>default</c> value if
/// either the key is not present or the value is not of type <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The type of the value associated with the specified key.</typeparam>
/// <param name="collection">The <see cref="IDictionary{TKey,TValue}"/> instance where <c>TValue</c> is <c>object</c>.</param>
/// <param name="key">The key whose value to get.</param>
/// <param name="value">When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the value parameter.</param>
/// <returns><c>true</c> if key was found, value is non-null, and value is of type <typeparamref name="T"/>; otherwise false.</returns>
public static bool TryGetValue<T>(this IDictionary<string, object> collection, string key, out T value)
{
if (collection == null)
{
throw Error.ArgumentNull("collection");
}
object valueObj;
if (collection.TryGetValue(key, out valueObj))
{
if (valueObj is T)
{
value = (T)valueObj;
return true;
}
}
value = default(T);
return false;
}
/// <summary>
/// Gets the value of <typeparamref name="T"/> associated with the specified key or throw an <see cref="T:System.InvalidOperationException"/>
/// if either the key is not present or the value is not of type <typeparamref name="T"/>.
/// </summary>
/// <param name="collection">The <see cref="IDictionary{TKey,TValue}"/> instance where <c>TValue</c> is <c>object</c>.</param>
/// <param name="key">The key whose value to get.</param>
/// <returns>An instance of type <typeparam name="T"/>.</returns>
public static T GetValue<T>(this IDictionary<string, object> collection, string key)
{
if (collection == null)
{
throw Error.ArgumentNull("collection");
}
T value;
if (collection.TryGetValue(key, out value))
{
return value;
}
throw Error.InvalidOperation(CommonWebApiResources.DictionaryMissingRequiredValue, collection.GetType().Name, key, typeof(T).Name);
}
internal static IEnumerable<KeyValuePair<string, TValue>> FindKeysWithPrefix<TValue>(this IDictionary<string, TValue> dictionary, string prefix)
{
if (dictionary == null)
{
throw Error.ArgumentNull("dictionary");
}
if (prefix == null)
{
throw Error.ArgumentNull("prefix");
}
TValue exactMatchValue;
if (dictionary.TryGetValue(prefix, out exactMatchValue))
{
yield return new KeyValuePair<string, TValue>(prefix, exactMatchValue);
}
foreach (var entry in dictionary)
{
string key = entry.Key;
if (key.Length <= prefix.Length)
{
continue;
}
if (!key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
continue;
}
// Everything is prefixed by the empty string
if (prefix.Length == 0)
{
yield return entry;
}
else
{
char charAfterPrefix = key[prefix.Length];
switch (charAfterPrefix)
{
case '[':
case '.':
yield return entry;
break;
}
}
}
}
internal static bool DoesAnyKeyHavePrefix<TValue>(this IDictionary<string, TValue> dictionary, string prefix)
{
return FindKeysWithPrefix(dictionary, prefix).Any();
}
/// <summary>
/// Adds a key/value pair of type <typeparamref name="T"/> to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary{object, object}"/>
/// if the key does not already exist.
/// </summary>
/// <typeparam name="T">The actual type of the dictionary value.</typeparam>
/// <param name="concurrentPropertyBag">A dictionary.</param>
/// <param name="key">The key of the element to add.</param>
/// <param name="factory">The function used to generate a value for the <paramref name="key"/>.</param>
/// <returns> The value for the key. This will be either the existing value for the <paramref name="key"/> if the key is already in the dictionary,
/// or the new value for the key as returned by <paramref name="factory"/> if the key was not in the dictionary.</returns>
internal static T GetOrAdd<T>(this ConcurrentDictionary<object, object> concurrentPropertyBag, object key, Func<object, T> factory)
{
Contract.Assert(concurrentPropertyBag != null);
Contract.Assert(key != null);
Contract.Assert(factory != null);
// SIMPLIFYING ASSUMPTION: this method is internal and keys are private so it's assumed that client code won't be able to
// replace the value with an object of a different type.
return (T)concurrentPropertyBag.GetOrAdd(key, valueFactory: k => factory(k));
}
}
}

View File

@@ -0,0 +1,263 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Web.Http.Properties;
namespace System.Web.Http
{
/// <summary>
/// Utility class for creating and unwrapping <see cref="Exception"/> instances.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Error", Justification = "This usage is okay.")]
internal static class Error
{
/// <summary>
/// Formats the specified resource string using <see cref="M:CultureInfo.CurrentCulture"/>.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An object array that contains zero or more objects to format.</param>
/// <returns>The formatted string.</returns>
[SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "Standard String.Format pattern and names.")]
internal static string Format(string format, params object[] args)
{
return String.Format(CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with the provided properties.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentException Argument(string messageFormat, params object[] messageArgs)
{
return new ArgumentException(Error.Format(messageFormat, messageArgs));
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with the provided properties.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentException Argument(string parameterName, string messageFormat, params object[] messageArgs)
{
return new ArgumentException(Error.Format(messageFormat, messageArgs), parameterName);
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an "http" or "https" URI.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentException ArgumentUriNotHttpOrHttpsScheme(string parameterName, Uri actualValue)
{
return new ArgumentException(Error.Format(CommonWebApiResources.ArgumentInvalidHttpUriScheme, actualValue, Uri.UriSchemeHttp, Uri.UriSchemeHttps), parameterName);
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an absolute URI.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentException ArgumentUriNotAbsolute(string parameterName, Uri actualValue)
{
return new ArgumentException(Error.Format(CommonWebApiResources.ArgumentInvalidAbsoluteUri, actualValue), parameterName);
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an absolute URI
/// without a query or fragment identifier and then logs it with <see cref="F:TraceLevel.Error"/>.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentException ArgumentUriHasQueryOrFragment(string parameterName, Uri actualValue)
{
return new ArgumentException(Error.Format(CommonWebApiResources.ArgumentUriHasQueryOrFragment, actualValue), parameterName);
}
/// <summary>
/// Creates an <see cref="ArgumentNullException"/> with the provided properties.
/// </summary>
/// <returns>The logged <see cref="Exception"/>.</returns>
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "The purpose of this API is to return an error for properties")]
internal static ArgumentNullException PropertyNull()
{
return new ArgumentNullException("value");
}
/// <summary>
/// Creates an <see cref="ArgumentNullException"/> with the provided properties.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentNullException ArgumentNull(string parameterName)
{
return new ArgumentNullException(parameterName);
}
/// <summary>
/// Creates an <see cref="ArgumentNullException"/> with the provided properties.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentNullException ArgumentNull(string parameterName, string messageFormat, params object[] messageArgs)
{
return new ArgumentNullException(parameterName, Error.Format(messageFormat, messageArgs));
}
/// <summary>
/// Creates an <see cref="ArgumentException"/> with a default message.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentException ArgumentNullOrEmpty(string parameterName)
{
return Error.Argument(parameterName, CommonWebApiResources.ArgumentNullOrEmpty, parameterName);
}
/// <summary>
/// Creates an <see cref="ArgumentOutOfRangeException"/> with the provided properties.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentOutOfRangeException ArgumentOutOfRange(string parameterName, object actualValue, string messageFormat, params object[] messageArgs)
{
return new ArgumentOutOfRangeException(parameterName, actualValue, Error.Format(messageFormat, messageArgs));
}
/// <summary>
/// Creates an <see cref="ArgumentOutOfRangeException"/> with a message saying that the argument must be greater than or equal to <paramref name="minValue"/>.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
/// <param name="minValue">The minimum size of the argument.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentOutOfRangeException ArgumentGreaterThanOrEqualTo(string parameterName, object actualValue, object minValue)
{
return new ArgumentOutOfRangeException(parameterName, actualValue, Error.Format(CommonWebApiResources.ArgumentMustBeGreaterThanOrEqualTo, minValue));
}
/// <summary>
/// Creates an <see cref="ArgumentOutOfRangeException"/> with a message saying that the argument must be less than or equal to <paramref name="maxValue"/>.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="actualValue">The value of the argument that causes this exception.</param>
/// <param name="maxValue">The maximum size of the argument.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ArgumentOutOfRangeException ArgumentMustBeLessThanOrEqualTo(string parameterName, object actualValue, object maxValue)
{
return new ArgumentOutOfRangeException(parameterName, actualValue, Error.Format(CommonWebApiResources.ArgumentMustBeLessThanOrEqualTo, maxValue));
}
/// <summary>
/// Creates an <see cref="KeyNotFoundException"/> with a message saying that the key was not found.
/// </summary>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static KeyNotFoundException KeyNotFound()
{
return new KeyNotFoundException();
}
/// <summary>
/// Creates an <see cref="KeyNotFoundException"/> with a message saying that the key was not found.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static KeyNotFoundException KeyNotFound(string messageFormat, params object[] messageArgs)
{
return new KeyNotFoundException(Error.Format(messageFormat, messageArgs));
}
/// <summary>
/// Creates an <see cref="ObjectDisposedException"/> initialized according to guidelines.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static ObjectDisposedException ObjectDisposed(string messageFormat, params object[] messageArgs)
{
// Pass in null, not disposedObject.GetType().FullName as per the above guideline
return new ObjectDisposedException(null, Error.Format(messageFormat, messageArgs));
}
/// <summary>
/// Creates an <see cref="OperationCanceledException"/> initialized with the provided parameters.
/// </summary>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static OperationCanceledException OperationCanceled()
{
return new OperationCanceledException();
}
/// <summary>
/// Creates an <see cref="OperationCanceledException"/> initialized with the provided parameters.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static OperationCanceledException OperationCanceled(string messageFormat, params object[] messageArgs)
{
return new OperationCanceledException(Error.Format(messageFormat, messageArgs));
}
/// <summary>
/// Creates an <see cref="InvalidEnumArgumentException"/>.
/// </summary>
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
/// <param name="invalidValue">The value of the argument that failed.</param>
/// <param name="enumClass">A <see cref="Type"/> that represents the enumeration class with the valid values.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static InvalidEnumArgumentException InvalidEnumArgument(string parameterName, int invalidValue, Type enumClass)
{
return new InvalidEnumArgumentException(parameterName, invalidValue, enumClass);
}
/// <summary>
/// Creates an <see cref="InvalidOperationException"/>.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static InvalidOperationException InvalidOperation(string messageFormat, params object[] messageArgs)
{
return new InvalidOperationException(Error.Format(messageFormat, messageArgs));
}
/// <summary>
/// Creates an <see cref="InvalidOperationException"/>.
/// </summary>
/// <param name="innerException">Inner exception</param>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static InvalidOperationException InvalidOperation(Exception innerException, string messageFormat, params object[] messageArgs)
{
return new InvalidOperationException(Error.Format(messageFormat, messageArgs), innerException);
}
/// <summary>
/// Creates an <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
/// <returns>The logged <see cref="Exception"/>.</returns>
internal static NotSupportedException NotSupported(string messageFormat, params object[] messageArgs)
{
return new NotSupportedException(Error.Format(messageFormat, messageArgs));
}
}
}

View File

@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Net.Http;
namespace System.Web.Http
{
/// <summary>
/// Various helper methods for the static members of <see cref="HttpMethod"/>.
/// </summary>
internal static class HttpMethodHelper
{
/// <summary>
/// Gets the static <see cref="HttpMethod"/> instance for any given HTTP method name.
/// </summary>
/// <param name="method">The HTTP request method.</param>
/// <returns>An existing static <see cref="HttpMethod"/> or a new instance if the method was not found.</returns>
internal static HttpMethod GetHttpMethod(string method)
{
if (String.IsNullOrEmpty(method))
{
return null;
}
if (String.Equals("GET", method, StringComparison.OrdinalIgnoreCase))
{
return HttpMethod.Get;
}
if (String.Equals("POST", method, StringComparison.OrdinalIgnoreCase))
{
return HttpMethod.Post;
}
if (String.Equals("PUT", method, StringComparison.OrdinalIgnoreCase))
{
return HttpMethod.Put;
}
if (String.Equals("DELETE", method, StringComparison.OrdinalIgnoreCase))
{
return HttpMethod.Delete;
}
if (String.Equals("HEAD", method, StringComparison.OrdinalIgnoreCase))
{
return HttpMethod.Head;
}
if (String.Equals("OPTIONS", method, StringComparison.OrdinalIgnoreCase))
{
return HttpMethod.Options;
}
if (String.Equals("TRACE", method, StringComparison.OrdinalIgnoreCase))
{
return HttpMethod.Trace;
}
return new HttpMethod(method);
}
}
}

View File

@@ -0,0 +1,208 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
namespace System.Web
{
/// <summary>
/// This is a container for prefix values. It normalizes all the values into dotted-form and then stores
/// them in a sorted array. All queries for prefixes are also normalized to dotted-form, and searches
/// for ContainsPrefix are done with a binary search.
/// </summary>
internal class PrefixContainer
{
private readonly ICollection<string> _originalValues;
private readonly string[] _sortedValues;
internal PrefixContainer(ICollection<string> values)
{
if (values == null)
{
throw new ArgumentNullException("values");
}
_originalValues = values;
_sortedValues = values.Where(val => val != null).ToArray();
Array.Sort(_sortedValues, StringComparer.OrdinalIgnoreCase);
}
internal bool ContainsPrefix(string prefix)
{
if (prefix == null)
{
throw new ArgumentNullException("prefix");
}
if (prefix.Length == 0)
{
return _sortedValues.Length > 0; // only match empty string when we have some value
}
return Array.BinarySearch(_sortedValues, prefix, new PrefixComparer(prefix)) > -1;
}
// Given "foo.bar", "foo.hello", "something.other", foo[abc].baz and asking for prefix "foo" will return:
// - "bar"/"foo.bar"
// - "hello"/"foo.hello"
// - "abc"/"foo[abc]"
internal IDictionary<string, string> GetKeysFromPrefix(string prefix)
{
IDictionary<string, string> result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var entry in _originalValues)
{
if (entry != null)
{
if (entry.Length == prefix.Length)
{
// No key in this entry
continue;
}
if (prefix.Length == 0)
{
GetKeyFromEmptyPrefix(entry, result);
}
else if (entry.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
GetKeyFromNonEmptyPrefix(prefix, entry, result);
}
}
}
return result;
}
private static void GetKeyFromEmptyPrefix(string entry, IDictionary<string, string> results)
{
string key;
int dotPosition = entry.IndexOf('.');
int bracketPosition = entry.IndexOf('[');
int delimiterPosition = -1;
if (dotPosition == -1)
{
if (bracketPosition != -1)
{
delimiterPosition = bracketPosition;
}
}
else
{
if (bracketPosition == -1)
{
delimiterPosition = dotPosition;
}
else
{
delimiterPosition = Math.Min(dotPosition, bracketPosition);
}
}
key = delimiterPosition == -1 ? entry : entry.Substring(0, delimiterPosition);
results[key] = key;
}
private static void GetKeyFromNonEmptyPrefix(string prefix, string entry, IDictionary<string, string> results)
{
string key = null;
string fullName = null;
int keyPosition = prefix.Length + 1;
switch (entry[prefix.Length])
{
case '.':
int dotPosition = entry.IndexOf('.', keyPosition);
if (dotPosition == -1)
{
dotPosition = entry.Length;
}
key = entry.Substring(keyPosition, dotPosition - keyPosition);
fullName = entry.Substring(0, dotPosition);
break;
case '[':
int bracketPosition = entry.IndexOf(']', keyPosition);
if (bracketPosition == -1)
{
// Malformed for dictionary
return;
}
key = entry.Substring(keyPosition, bracketPosition - keyPosition);
fullName = entry.Substring(0, bracketPosition + 1);
break;
default:
return;
}
if (!results.ContainsKey(key))
{
results.Add(key, fullName);
}
}
internal static bool IsPrefixMatch(string prefix, string testString)
{
if (testString == null)
{
return false;
}
if (prefix.Length == 0)
{
return true; // shortcut - non-null testString matches empty prefix
}
if (prefix.Length > testString.Length)
{
return false; // not long enough
}
if (!testString.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
return false; // prefix doesn't match
}
if (testString.Length == prefix.Length)
{
return true; // exact match
}
// invariant: testString.Length > prefix.Length
switch (testString[prefix.Length])
{
case '.':
case '[':
return true; // known delimiters
default:
return false; // not known delimiter
}
}
private class PrefixComparer : IComparer<String>
{
private string _prefix;
public PrefixComparer(string prefix)
{
_prefix = prefix;
}
public int Compare(string x, string y)
{
string testString = Object.ReferenceEquals(x, _prefix) ? y : x;
if (IsPrefixMatch(_prefix, testString))
{
return 0;
}
return StringComparer.OrdinalIgnoreCase.Compare(x, y);
}
}
}
}

View File

@@ -0,0 +1,387 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
namespace System.Threading.Tasks
{
/// <summary>
/// Helpers for safely using Task libraries.
/// </summary>
internal static class TaskHelpers
{
private static Task _defaultCompleted = FromResult<AsyncVoid>(default(AsyncVoid));
/// <summary>
/// Returns a canceled Task. The task is completed, IsCanceled = True, IsFaulted = False.
/// </summary>
internal static Task Canceled()
{
return CancelCache<AsyncVoid>.Canceled;
}
/// <summary>
/// Returns a canceled Task of the given type. The task is completed, IsCanceled = True, IsFaulted = False.
/// </summary>
internal static Task<TResult> Canceled<TResult>()
{
return CancelCache<TResult>.Canceled;
}
/// <summary>
/// Returns a completed task that has no result.
/// </summary>
internal static Task Completed()
{
return _defaultCompleted;
}
/// <summary>
/// Returns an error task. The task is Completed, IsCanceled = False, IsFaulted = True
/// </summary>
internal static Task FromError(Exception exception)
{
return FromError<AsyncVoid>(exception);
}
/// <summary>
/// Returns an error task of the given type. The task is Completed, IsCanceled = False, IsFaulted = True
/// </summary>
/// <typeparam name="TResult"></typeparam>
internal static Task<TResult> FromError<TResult>(Exception exception)
{
TaskCompletionSource<TResult> tcs = new TaskCompletionSource<TResult>();
tcs.SetException(exception);
return tcs.Task;
}
/// <summary>
/// Returns an error task of the given type. The task is Completed, IsCanceled = False, IsFaulted = True
/// </summary>
internal static Task FromErrors(IEnumerable<Exception> exceptions)
{
return FromErrors<AsyncVoid>(exceptions);
}
/// <summary>
/// Returns an error task of the given type. The task is Completed, IsCanceled = False, IsFaulted = True
/// </summary>
internal static Task<TResult> FromErrors<TResult>(IEnumerable<Exception> exceptions)
{
TaskCompletionSource<TResult> tcs = new TaskCompletionSource<TResult>();
tcs.SetException(exceptions);
return tcs.Task;
}
/// <summary>
/// Returns a successful completed task with the given result.
/// </summary>
internal static Task<TResult> FromResult<TResult>(TResult result)
{
TaskCompletionSource<TResult> tcs = new TaskCompletionSource<TResult>();
tcs.SetResult(result);
return tcs.Task;
}
/// <summary>
/// Return a task that runs all the tasks inside the iterator sequentially. It stops as soon
/// as one of the tasks fails or cancels, or after all the tasks have run succesfully.
/// </summary>
/// <param name="asyncIterator">collection of tasks to wait on</param>
/// <param name="cancellationToken">cancellation token</param>
/// <returns>a task that signals completed when all the incoming tasks are finished.</returns>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is propagated in a Task.")]
internal static Task Iterate(IEnumerable<Task> asyncIterator, CancellationToken cancellationToken = default(CancellationToken))
{
Contract.Assert(asyncIterator != null);
IEnumerator<Task> enumerator = null;
try
{
enumerator = asyncIterator.GetEnumerator();
Task task = IterateImpl(enumerator, cancellationToken);
return (enumerator != null) ? task.Finally(enumerator.Dispose) : task;
}
catch (Exception ex)
{
return TaskHelpers.FromError(ex);
}
}
/// <summary>
/// Provides the implementation of the Iterate method.
/// Contains special logic to help speed up common cases.
/// </summary>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is propagated in a Task.")]
internal static Task IterateImpl(IEnumerator<Task> enumerator, CancellationToken cancellationToken)
{
try
{
while (true)
{
// short-circuit: iteration canceled
if (cancellationToken.IsCancellationRequested)
{
return TaskHelpers.Canceled();
}
// short-circuit: iteration complete
if (!enumerator.MoveNext())
{
return TaskHelpers.Completed();
}
// fast case: Task completed synchronously & successfully
Task currentTask = enumerator.Current;
if (currentTask.Status == TaskStatus.RanToCompletion)
{
continue;
}
// fast case: Task completed synchronously & unsuccessfully
if (currentTask.IsCanceled || currentTask.IsFaulted)
{
return currentTask;
}
// slow case: Task isn't yet complete
return IterateImplIncompleteTask(enumerator, currentTask, cancellationToken);
}
}
catch (Exception ex)
{
return TaskHelpers.FromError(ex);
}
}
/// <summary>
/// Fallback for IterateImpl when the antecedent Task isn't yet complete.
/// </summary>
internal static Task IterateImplIncompleteTask(IEnumerator<Task> enumerator, Task currentTask, CancellationToken cancellationToken)
{
// There's a race condition here, the antecedent Task could complete between
// the check in Iterate and the call to Then below. If this happens, we could
// end up growing the stack indefinitely. But the chances of (a) even having
// enough Tasks in the enumerator in the first place and of (b) *every* one
// of them hitting this race condition are so extremely remote that it's not
// worth worrying about.
return currentTask.Then(() => IterateImpl(enumerator, cancellationToken));
}
/// <summary>
/// Replacement for Task.Factory.StartNew when the code can run synchronously.
/// We run the code immediately and avoid the thread switch.
/// This is used to help synchronous code implement task interfaces.
/// </summary>
/// <param name="action">action to run synchronouslyt</param>
/// <param name="token">cancellation token. This is only checked before we run the task, and if cancelled, we immediately return a cancelled task.</param>
/// <returns>a task who result is the result from Func()</returns>
/// <remarks>
/// Avoid calling Task.Factory.StartNew.
/// This avoids gotchas with StartNew:
/// - ensures cancellation token is checked (StartNew doesn't check cancellation tokens).
/// - Keeps on the same thread.
/// - Avoids switching synchronization contexts.
/// Also take in a lambda so that we can wrap in a try catch and honor task failure semantics.
/// </remarks>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The caught exception type is reflected into a faulted task.")]
public static Task RunSynchronously(Action action, CancellationToken token = default(CancellationToken))
{
if (token.IsCancellationRequested)
{
return Canceled();
}
try
{
action();
return Completed();
}
catch (Exception e)
{
return FromError(e);
}
}
/// <summary>
/// Replacement for Task.Factory.StartNew when the code can run synchronously.
/// We run the code immediately and avoid the thread switch.
/// This is used to help synchronous code implement task interfaces.
/// </summary>
/// <typeparam name="TResult">type of result that task will return.</typeparam>
/// <param name="func">function to run synchronously and produce result</param>
/// <param name="cancellationToken">cancellation token. This is only checked before we run the task, and if cancelled, we immediately return a cancelled task.</param>
/// <returns>a task who result is the result from Func()</returns>
/// <remarks>
/// Avoid calling Task.Factory.StartNew.
/// This avoids gotchas with StartNew:
/// - ensures cancellation token is checked (StartNew doesn't check cancellation tokens).
/// - Keeps on the same thread.
/// - Avoids switching synchronization contexts.
/// Also take in a lambda so that we can wrap in a try catch and honor task failure semantics.
/// </remarks>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The caught exception type is reflected into a faulted task.")]
internal static Task<TResult> RunSynchronously<TResult>(Func<TResult> func, CancellationToken cancellationToken = default(CancellationToken))
{
if (cancellationToken.IsCancellationRequested)
{
return Canceled<TResult>();
}
try
{
return FromResult(func());
}
catch (Exception e)
{
return FromError<TResult>(e);
}
}
/// <summary>
/// Overload of RunSynchronously that avoids a call to Unwrap().
/// This overload is useful when func() starts doing some synchronous work and then hits IO and
/// needs to create a task to finish the work.
/// </summary>
/// <typeparam name="TResult">type of result that Task will return</typeparam>
/// <param name="func">function that returns a task</param>
/// <param name="cancellationToken">cancellation token. This is only checked before we run the task, and if cancelled, we immediately return a cancelled task.</param>
/// <returns>a task, created by running func().</returns>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The caught exception type is reflected into a faulted task.")]
internal static Task<TResult> RunSynchronously<TResult>(Func<Task<TResult>> func, CancellationToken cancellationToken = default(CancellationToken))
{
if (cancellationToken.IsCancellationRequested)
{
return Canceled<TResult>();
}
try
{
return func();
}
catch (Exception e)
{
return FromError<TResult>(e);
}
}
/// <summary>
/// Update the completion source if the task failed (cancelled or faulted). No change to completion source if the task succeeded.
/// </summary>
/// <typeparam name="TResult">result type of completion source</typeparam>
/// <param name="tcs">completion source to update</param>
/// <param name="source">task to update from.</param>
/// <returns>true on success</returns>
internal static bool SetIfTaskFailed<TResult>(this TaskCompletionSource<TResult> tcs, Task source)
{
switch (source.Status)
{
case TaskStatus.Canceled:
case TaskStatus.Faulted:
return tcs.TrySetFromTask(source);
}
return false;
}
/// <summary>
/// Set a completion source from the given Task.
/// </summary>
/// <typeparam name="TResult">result type for completion source.</typeparam>
/// <param name="tcs">completion source to set</param>
/// <param name="source">Task to get values from.</param>
/// <returns>true if this successfully sets the completion source.</returns>
[SuppressMessage("Microsoft.WebAPI", "CR4001:DoNotCallProblematicMethodsOnTask", Justification = "This is a known safe usage of Task.Result, since it only occurs when we know the task's state to be completed.")]
internal static bool TrySetFromTask<TResult>(this TaskCompletionSource<TResult> tcs, Task source)
{
if (source.Status == TaskStatus.Canceled)
{
return tcs.TrySetCanceled();
}
if (source.Status == TaskStatus.Faulted)
{
return tcs.TrySetException(source.Exception.InnerExceptions);
}
if (source.Status == TaskStatus.RanToCompletion)
{
Task<TResult> taskOfResult = source as Task<TResult>;
return tcs.TrySetResult(taskOfResult == null ? default(TResult) : taskOfResult.Result);
}
return false;
}
/// <summary>
/// Set a completion source from the given Task. If the task ran to completion and the result type doesn't match
/// the type of the completion source, then a default value will be used. This is useful for converting Task into
/// Task{AsyncVoid}, but it can also accidentally be used to introduce data loss (by passing the wrong
/// task type), so please execute this method with care.
/// </summary>
/// <typeparam name="TResult">result type for completion source.</typeparam>
/// <param name="tcs">completion source to set</param>
/// <param name="source">Task to get values from.</param>
/// <returns>true if this successfully sets the completion source.</returns>
[SuppressMessage("Microsoft.WebAPI", "CR4001:DoNotCallProblematicMethodsOnTask", Justification = "This is a known safe usage of Task.Result, since it only occurs when we know the task's state to be completed.")]
internal static bool TrySetFromTask<TResult>(this TaskCompletionSource<Task<TResult>> tcs, Task source)
{
if (source.Status == TaskStatus.Canceled)
{
return tcs.TrySetCanceled();
}
if (source.Status == TaskStatus.Faulted)
{
return tcs.TrySetException(source.Exception.InnerExceptions);
}
if (source.Status == TaskStatus.RanToCompletion)
{
// Sometimes the source task is Task<Task<TResult>>, and sometimes it's Task<TResult>.
// The latter usually happens when we're in the middle of a sync-block postback where
// the continuation is a function which returns Task<TResult> rather than just TResult,
// but the originating task was itself just Task<TResult>. An example of this can be
// found in TaskExtensions.CatchImpl().
Task<Task<TResult>> taskOfTaskOfResult = source as Task<Task<TResult>>;
if (taskOfTaskOfResult != null)
{
return tcs.TrySetResult(taskOfTaskOfResult.Result);
}
Task<TResult> taskOfResult = source as Task<TResult>;
if (taskOfResult != null)
{
return tcs.TrySetResult(taskOfResult);
}
return tcs.TrySetResult(TaskHelpers.FromResult(default(TResult)));
}
return false;
}
/// <summary>
/// Used as the T in a "conversion" of a Task into a Task{T}
/// </summary>
private struct AsyncVoid
{
}
/// <summary>
/// This class is a convenient cache for per-type cancelled tasks
/// </summary>
private static class CancelCache<TResult>
{
public static readonly Task<TResult> Canceled = GetCancelledTask();
private static Task<TResult> GetCancelledTask()
{
TaskCompletionSource<TResult> tcs = new TaskCompletionSource<TResult>();
tcs.SetCanceled();
return tcs.Task;
}
}
}
}

File diff suppressed because it is too large Load Diff