2010-10-18 21:28:56 +08:00
#region MIT License
2013-01-11 19:32:38 +08:00
/ *
2010-10-18 21:28:56 +08:00
* Ext . cs
2012-10-01 14:26:31 +08:00
* IsPredefinedScheme and MaybeUri methods derived from System . Uri . cs
* GetStatusDescription method derived from System . Net . HttpListenerResponse . cs
2010-10-18 21:28:56 +08:00
*
* The MIT License
*
2013-01-22 19:46:32 +08:00
* Copyright ( c ) 2010 - 2013 sta . blockhead
2012-09-10 00:36:22 +08:00
*
2012-12-05 21:10:15 +08:00
* System . Uri . cs
2013-01-22 19:46:32 +08:00
* ( C ) 2001 Garrett Rooney
* ( C ) 2003 Ian MacLean
* ( C ) 2003 Ben Maurer
* Copyright ( C ) 2003 , 2005 , 2009 Novell , Inc . ( http : //www.novell.com)
* Copyright ( c ) 2009 Stephane Delcroix
2012-12-05 21:10:15 +08:00
*
* System . Net . HttpListenerResponse . cs
2013-01-22 19:46:32 +08:00
* Copyright ( C ) 2003 , 2005 , 2009 Novell , Inc . ( http : //www.novell.com)
2012-12-05 21:10:15 +08:00
*
2010-10-18 21:28:56 +08:00
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , 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 NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
* /
#endregion
using System ;
using System.Collections.Generic ;
2012-09-10 00:36:22 +08:00
using System.Collections.Specialized ;
2012-07-31 09:36:52 +08:00
using System.IO ;
2010-10-25 19:56:26 +08:00
using System.Linq ;
2012-09-24 14:01:25 +08:00
using System.Net.Sockets ;
2012-07-31 09:36:52 +08:00
using System.Text ;
2012-09-10 00:36:22 +08:00
using WebSocketSharp.Net ;
2013-01-22 19:46:32 +08:00
using WebSocketSharp.Net.WebSockets ;
2010-10-18 21:28:56 +08:00
2012-10-01 14:26:31 +08:00
namespace WebSocketSharp {
2012-12-05 21:10:15 +08:00
/// <summary>
/// Provides a set of static methods for the websocket-sharp.
/// </summary>
2012-10-01 14:26:31 +08:00
public static class Ext {
2013-03-11 15:28:34 +08:00
#region Field
private const string _tspecials = "()<>@,;:\\\"/[]?={} \t" ;
#endregion
2012-12-05 21:10:15 +08:00
#region Private Methods
private static void times ( this ulong n , Action act )
{
for ( ulong i = 0 ; i < n ; i + + )
act ( ) ;
}
#endregion
2013-03-11 15:28:34 +08:00
#region Internal Method
2013-03-14 14:47:27 +08:00
internal static bool IsText ( this string value )
{
int len = value . Length ;
for ( int i = 0 ; i < len ; i + + )
{
char c = value [ i ] ;
if ( c < 0x20 & & ! "\r\n\t" . Contains ( c ) )
return false ;
if ( c = = 0x7f )
return false ;
if ( c = = '\n' & & + + i < len )
{
c = value [ i ] ;
if ( ! " \t" . Contains ( c ) )
return false ;
}
}
return true ;
}
2013-03-11 15:28:34 +08:00
internal static bool IsToken ( this string value )
{
foreach ( char c in value )
{
if ( c < 0x20 | | c > = 0x7f | | _tspecials . Contains ( c ) )
return false ;
}
return true ;
}
#endregion
2012-12-05 21:10:15 +08:00
#region Public Methods
/// <summary>
2013-01-28 15:22:24 +08:00
/// Accepts a WebSocket connection by the <see cref="TcpListener"/>.
2012-12-05 21:10:15 +08:00
/// </summary>
/// <returns>
2013-01-28 15:22:24 +08:00
/// A <see cref="TcpListenerWebSocketContext"/> that contains a WebSocket connection.
2012-12-05 21:10:15 +08:00
/// </returns>
2013-01-28 15:22:24 +08:00
/// <param name="listener">
/// A <see cref="TcpListener"/> that provides a TCP connection to accept a WebSocket connection.
2012-12-05 21:10:15 +08:00
/// </param>
2012-12-11 14:49:01 +08:00
/// <param name="secure">
/// A <see cref="bool"/> that indicates a secure connection or not. (<c>true</c> indicates a secure connection.)
/// </param>
2012-12-05 21:10:15 +08:00
/// <exception cref="ArgumentNullException">
2013-01-28 15:22:24 +08:00
/// <paramref name="listener"/> is <see langword="null"/>.
2012-12-05 21:10:15 +08:00
/// </exception>
2013-01-28 15:22:24 +08:00
public static TcpListenerWebSocketContext AcceptWebSocket ( this TcpListener listener , bool secure )
2012-09-24 14:01:25 +08:00
{
2013-01-28 15:22:24 +08:00
if ( listener . IsNull ( ) )
throw new ArgumentNullException ( "listener" ) ;
2012-12-05 21:10:15 +08:00
2013-01-28 15:22:24 +08:00
var client = listener . AcceptTcpClient ( ) ;
2012-12-11 14:49:01 +08:00
return new TcpListenerWebSocketContext ( client , secure ) ;
2012-09-24 14:01:25 +08:00
}
2013-01-28 15:22:24 +08:00
/// <summary>
/// Accepts a WebSocket connection asynchronously by the <see cref="TcpListener"/>.
/// </summary>
/// <param name="listener">
/// A <see cref="TcpListener"/> that provides a TCP connection to accept a WebSocket connection.
/// </param>
/// <param name="secure">
/// A <see cref="bool"/> that indicates a secure connection or not. (<c>true</c> indicates a secure connection.)
/// </param>
/// <param name="completed">
/// An Action<TcpListenerWebSocketContext> delegate that contains the method(s) that is called when an asynchronous operation completes.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="listener"/> is <see langword="null"/>.
/// </exception>
public static void AcceptWebSocketAsync ( this TcpListener listener , bool secure , Action < TcpListenerWebSocketContext > completed )
{
if ( listener . IsNull ( ) )
throw new ArgumentNullException ( "listener" ) ;
AsyncCallback callback = ( ar ) = >
{
var client = listener . EndAcceptTcpClient ( ar ) ;
var context = new TcpListenerWebSocketContext ( client , secure ) ;
completed ( context ) ;
} ;
listener . BeginAcceptTcpClient ( callback , null ) ;
}
2013-03-11 15:28:34 +08:00
/// <summary>
/// Determines whether the specified <see cref="string"/> contains any of characters
/// in the specified array of <see cref="char"/>.
/// </summary>
/// <returns>
/// <c>true</c> if <paramref name="str"/> contains any of <paramref name="chars"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="str">
/// A <see cref="string"/> to test.
/// </param>
/// <param name="chars">
/// An array of <see cref="char"/> that contains characters to find.
/// </param>
public static bool Contains ( this string str , params char [ ] chars )
{
return str . IsNullOrEmpty ( )
? false
: chars . Length = = 0
? true
: str . IndexOfAny ( chars ) ! = - 1 ;
}
2012-10-22 13:58:43 +08:00
/// <summary>
/// Emit the specified <see cref="EventHandler"/> delegate if is not <see langword="null"/>.
/// </summary>
/// <param name="eventHandler">
2012-12-05 21:10:15 +08:00
/// An <see cref="EventHandler"/> to emit.
2012-10-22 13:58:43 +08:00
/// </param>
/// <param name="sender">
2012-12-05 21:10:15 +08:00
/// An <see cref="object"/> that emits the <paramref name="eventHandler"/>.
2012-10-22 13:58:43 +08:00
/// </param>
/// <param name="e">
/// An <see cref="EventArgs"/> that contains no event data.
/// </param>
2012-08-01 10:38:40 +08:00
public static void Emit (
this EventHandler eventHandler , object sender , EventArgs e )
{
2012-10-22 13:58:43 +08:00
if ( ! eventHandler . IsNull ( ) )
2012-08-01 10:38:40 +08:00
eventHandler ( sender , e ) ;
}
2012-10-22 13:58:43 +08:00
/// <summary>
2013-01-11 19:32:38 +08:00
/// Emit the specified <b>EventHandler<TEventArgs></b> delegate if is not <see langword="null"/>.
2012-10-22 13:58:43 +08:00
/// </summary>
/// <param name="eventHandler">
2013-01-11 19:32:38 +08:00
/// An <b>EventHandler<TEventArgs></b> to emit.
2012-10-22 13:58:43 +08:00
/// </param>
/// <param name="sender">
2012-12-05 21:10:15 +08:00
/// An <see cref="object"/> that emits the <paramref name="eventHandler"/>.
2012-10-22 13:58:43 +08:00
/// </param>
/// <param name="e">
2013-01-11 19:32:38 +08:00
/// A <b>TEventArgs</b> that contains the event data.
2012-10-22 13:58:43 +08:00
/// </param>
/// <typeparam name="TEventArgs">
/// The type of the event data generated by the event.
/// </typeparam>
2012-08-01 10:38:40 +08:00
public static void Emit < TEventArgs > (
this EventHandler < TEventArgs > eventHandler , object sender , TEventArgs e )
where TEventArgs : EventArgs
{
2012-10-22 13:58:43 +08:00
if ( ! eventHandler . IsNull ( ) )
2012-08-01 10:38:40 +08:00
eventHandler ( sender , e ) ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Determines whether the specified <see cref="int"/> equals the specified <see cref="char"/> as <see cref="byte"/>.
2013-01-11 19:32:38 +08:00
/// And save this specified <see cref="int"/> as <see cref="byte"/> to the specified <strong>List<byte></strong>.
2012-12-05 21:10:15 +08:00
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="value"/> parameter equals the <paramref name="c"/> parameter as <see cref="byte"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="value">
/// An <see cref="int"/> to compare.
/// </param>
/// <param name="c">
/// A <see cref="char"/> to compare.
/// </param>
/// <param name="dest">
2013-01-11 19:32:38 +08:00
/// A <strong>List<byte></strong> to save the <paramref name="value"/> as <see cref="byte"/>.
2012-12-05 21:10:15 +08:00
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// Is thrown when the <paramref name="value"/> parameter passed to a method is invalid because it is outside the allowable range of values as <see cref="byte"/>.
/// </exception>
2012-07-31 09:36:52 +08:00
public static bool EqualsAndSaveTo ( this int value , char c , List < byte > dest )
{
2012-12-05 21:10:15 +08:00
if ( value < 0 | | value > 255 )
2012-09-01 16:01:05 +08:00
throw new ArgumentOutOfRangeException ( "value" ) ;
2012-09-11 12:21:47 +08:00
2012-12-05 21:10:15 +08:00
var b = ( byte ) value ;
2012-07-31 09:36:52 +08:00
dest . Add ( b ) ;
2012-12-05 21:10:15 +08:00
2012-07-31 09:36:52 +08:00
return b = = Convert . ToByte ( c ) ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Determines whether the entry with the specified key exists in the specified <see cref="NameValueCollection"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the entry with the <paramref name="name"/> exists in the <paramref name="collection"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="collection">
/// A <see cref="NameValueCollection"/> that contains the entries.
/// </param>
/// <param name="name">
/// A <see cref="string"/> that contains the key of the entry to find.
/// </param>
public static bool Exists ( this NameValueCollection collection , string name )
2012-09-10 00:36:22 +08:00
{
2012-12-05 21:10:15 +08:00
return collection . IsNull ( )
? false
: ! collection [ name ] . IsNull ( ) ;
2012-09-10 00:36:22 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Determines whether the entry with the specified both key and value exists in the specified <see cref="NameValueCollection"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the entry with the both <paramref name="name"/> and <paramref name="value"/> exists in the <paramref name="collection"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="collection">
/// A <see cref="NameValueCollection"/> that contains the entries.
/// </param>
/// <param name="name">
/// A <see cref="string"/> that contains the key of the entry to find.
/// </param>
/// <param name="value">
/// A <see cref="string"/> that contains the value of the entry to find.
/// </param>
public static bool Exists ( this NameValueCollection collection , string name , string value )
2012-09-10 00:36:22 +08:00
{
2012-12-05 21:10:15 +08:00
if ( collection . IsNull ( ) )
return false ;
var values = collection [ name ] ;
2012-10-22 13:58:43 +08:00
if ( values . IsNull ( ) )
2012-09-10 00:36:22 +08:00
return false ;
foreach ( string v in values . Split ( ',' ) )
if ( String . Compare ( v . Trim ( ) , value , true ) = = 0 )
return true ;
return false ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Gets the absolute path from the specified <see cref="Uri"/>.
/// </summary>
/// <returns>
/// A <see cref="string"/> that contains the absolute path if got successfully; otherwise, <see langword="null"/>.
/// </returns>
/// <param name="uri">
/// A <see cref="Uri"/> that contains the URI to get the absolute path from.
/// </param>
2012-10-22 13:58:43 +08:00
public static string GetAbsolutePath ( this Uri uri )
{
2012-12-05 21:10:15 +08:00
if ( uri . IsNull ( ) )
return null ;
2012-10-22 13:58:43 +08:00
if ( uri . IsAbsoluteUri )
return uri . AbsolutePath ;
var uriString = uri . OriginalString ;
var i = uriString . IndexOf ( '/' ) ;
if ( i ! = 0 )
2012-12-05 21:10:15 +08:00
return null ;
2012-10-22 13:58:43 +08:00
2012-12-05 21:10:15 +08:00
i = uriString . IndexOfAny ( new [ ] { '?' , '#' } ) ;
return i > 0
? uriString . Substring ( 0 , i )
: uriString ;
2012-10-22 13:58:43 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
2013-02-11 21:57:01 +08:00
/// Gets the description of the HTTP status code using the specified <see cref="WebSocketSharp.Net.HttpStatusCode"/>.
2012-12-05 21:10:15 +08:00
/// </summary>
/// <returns>
2013-02-11 21:57:01 +08:00
/// A <see cref="string"/> that contains the description of the HTTP status code.
2012-12-05 21:10:15 +08:00
/// </returns>
/// <param name="code">
2013-02-11 21:57:01 +08:00
/// One of <see cref="WebSocketSharp.Net.HttpStatusCode"/> values that contains an HTTP status code.
2012-12-05 21:10:15 +08:00
/// </param>
2012-10-01 14:26:31 +08:00
public static string GetDescription ( this HttpStatusCode code )
{
return ( ( int ) code ) . GetStatusDescription ( ) ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Gets the name from the specified <see cref="string"/> that contains a pair of name and value are separated by a separator string.
/// </summary>
/// <returns>
/// A <see cref="string"/> that contains the name if any; otherwise, <c>null</c>.
/// </returns>
/// <param name="nameAndValue">
/// A <see cref="string"/> that contains a pair of name and value are separated by a separator string.
/// </param>
/// <param name="separator">
/// A <see cref="string"/> that contains a separator string.
/// </param>
public static string GetName ( this string nameAndValue , string separator )
{
if ( nameAndValue . IsNullOrEmpty ( ) )
return null ;
if ( separator . IsNullOrEmpty ( ) )
return null ;
var i = nameAndValue . IndexOf ( separator ) ;
return i > 0
? nameAndValue . Substring ( 0 , i ) . Trim ( )
: null ;
}
/// <summary>
/// Gets the name and value from the specified <see cref="string"/> that contains a pair of name and value are separated by a separator string.
/// </summary>
/// <returns>
2013-01-11 19:32:38 +08:00
/// A <b>KeyValuePair<string, string></b> that contains the name and value if any.
2012-12-05 21:10:15 +08:00
/// </returns>
/// <param name="nameAndValue">
/// A <see cref="string"/> that contains a pair of name and value are separated by a separator string.
/// </param>
/// <param name="separator">
/// A <see cref="string"/> that contains a separator string.
/// </param>
public static KeyValuePair < string , string > GetNameAndValue ( this string nameAndValue , string separator )
{
var name = nameAndValue . GetName ( separator ) ;
var value = nameAndValue . GetValue ( separator ) ;
return ! name . IsNull ( )
? new KeyValuePair < string , string > ( name , value )
: new KeyValuePair < string , string > ( null , null ) ;
}
/// <summary>
2013-02-11 21:57:01 +08:00
/// Gets the description of the HTTP status code using the specified <see cref="int"/>.
2012-12-05 21:10:15 +08:00
/// </summary>
/// <returns>
2013-02-11 21:57:01 +08:00
/// A <see cref="string"/> that contains the description of the HTTP status code.
2012-12-05 21:10:15 +08:00
/// </returns>
/// <param name="code">
2013-02-11 21:57:01 +08:00
/// An <see cref="int"/> that contains an HTTP status code.
2012-12-05 21:10:15 +08:00
/// </param>
2012-10-01 14:26:31 +08:00
public static string GetStatusDescription ( this int code )
{
switch ( code )
{
case 100 : return "Continue" ;
case 101 : return "Switching Protocols" ;
case 102 : return "Processing" ;
case 200 : return "OK" ;
case 201 : return "Created" ;
case 202 : return "Accepted" ;
case 203 : return "Non-Authoritative Information" ;
case 204 : return "No Content" ;
case 205 : return "Reset Content" ;
case 206 : return "Partial Content" ;
case 207 : return "Multi-Status" ;
case 300 : return "Multiple Choices" ;
case 301 : return "Moved Permanently" ;
case 302 : return "Found" ;
case 303 : return "See Other" ;
case 304 : return "Not Modified" ;
case 305 : return "Use Proxy" ;
case 307 : return "Temporary Redirect" ;
case 400 : return "Bad Request" ;
case 401 : return "Unauthorized" ;
case 402 : return "Payment Required" ;
case 403 : return "Forbidden" ;
case 404 : return "Not Found" ;
case 405 : return "Method Not Allowed" ;
case 406 : return "Not Acceptable" ;
case 407 : return "Proxy Authentication Required" ;
case 408 : return "Request Timeout" ;
case 409 : return "Conflict" ;
case 410 : return "Gone" ;
case 411 : return "Length Required" ;
case 412 : return "Precondition Failed" ;
case 413 : return "Request Entity Too Large" ;
case 414 : return "Request-Uri Too Long" ;
case 415 : return "Unsupported Media Type" ;
case 416 : return "Requested Range Not Satisfiable" ;
case 417 : return "Expectation Failed" ;
case 422 : return "Unprocessable Entity" ;
case 423 : return "Locked" ;
case 424 : return "Failed Dependency" ;
case 500 : return "Internal Server Error" ;
case 501 : return "Not Implemented" ;
case 502 : return "Bad Gateway" ;
case 503 : return "Service Unavailable" ;
case 504 : return "Gateway Timeout" ;
case 505 : return "Http Version Not Supported" ;
case 507 : return "Insufficient Storage" ;
}
return String . Empty ;
}
2012-10-16 19:31:50 +08:00
/// <summary>
2012-12-05 21:10:15 +08:00
/// Gets the value from the specified <see cref="string"/> that contains a pair of name and value are separated by a separator string.
2012-10-16 19:31:50 +08:00
/// </summary>
/// <returns>
2012-10-22 13:58:43 +08:00
/// A <see cref="string"/> that contains the value if any; otherwise, <c>null</c>.
2012-10-16 19:31:50 +08:00
/// </returns>
/// <param name="nameAndValue">
/// A <see cref="string"/> that contains a pair of name and value are separated by a separator string.
/// </param>
/// <param name="separator">
/// A <see cref="string"/> that contains a separator string.
/// </param>
public static string GetValue ( this string nameAndValue , string separator )
{
2012-12-05 21:10:15 +08:00
if ( nameAndValue . IsNullOrEmpty ( ) )
2012-10-16 19:31:50 +08:00
return null ;
2012-12-05 21:10:15 +08:00
if ( separator . IsNullOrEmpty ( ) )
return null ;
2012-10-16 19:31:50 +08:00
2012-12-05 21:10:15 +08:00
var i = nameAndValue . IndexOf ( separator ) ;
return i > = 0 & & i < nameAndValue . Length - 1
? nameAndValue . Substring ( i + 1 ) . Trim ( )
: null ;
2012-07-31 09:36:52 +08:00
}
2012-10-22 13:58:43 +08:00
/// <summary>
2012-12-05 21:10:15 +08:00
/// Determines whether the specified <see cref="string"/> is a <see cref="String.Empty"/>.
2012-10-22 13:58:43 +08:00
/// </summary>
/// <returns>
2013-03-11 15:28:34 +08:00
/// <c>true</c> if <paramref name="value"/> is <see cref="String.Empty"/>; otherwise, <c>false</c>.
2012-10-22 13:58:43 +08:00
/// </returns>
/// <param name="value">
/// A <see cref="string"/> to test.
/// </param>
public static bool IsEmpty ( this string value )
{
return value = = String . Empty ? true : false ;
}
2013-03-11 15:28:34 +08:00
/// <summary>
/// Determines whether the specified <see cref="string"/> is enclosed in the specified <see cref="char"/>.
/// </summary>
/// <returns>
/// <c>true</c> if <paramref name="str"/> is enclosed in <paramref name="c"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="str">
/// A <see cref="string"/> to test.
/// </param>
/// <param name="c">
/// A <see cref="char"/> that contains character to find.
/// </param>
public static bool IsEnclosedIn ( this string str , char c )
{
return str . IsNullOrEmpty ( )
? false
: str [ 0 ] = = c & & str [ str . Length - 1 ] = = c ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Determines whether the specified <see cref="WebSocketSharp.ByteOrder"/> is host (this computer architecture) byte order.
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="order"/> parameter is host byte order; otherwise, <c>false</c>.
/// </returns>
/// <param name="order">
/// A <see cref="WebSocketSharp.ByteOrder"/> to test.
/// </param>
public static bool IsHostOrder ( this ByteOrder order )
{
// true : !(true ^ true) or !(false ^ false)
// false: !(true ^ false) or !(false ^ true)
return ! ( BitConverter . IsLittleEndian ^ ( order = = ByteOrder . LITTLE ) ) ;
}
2013-02-26 10:39:59 +08:00
/// <summary>
/// Determines whether the specified <see cref="System.Net.IPAddress"/> represents a local IP address.
/// </summary>
/// <returns>
/// <c>true</c> if <paramref name="address"/> represents a local IP address; otherwise, <c>false</c>.
/// </returns>
/// <param name="address">
/// A <see cref="System.Net.IPAddress"/> to test.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="address"/> is <see langword="null"/>.
/// </exception>
public static bool IsLocal ( this System . Net . IPAddress address )
{
if ( address . IsNull ( ) )
throw new ArgumentNullException ( "address" ) ;
if ( System . Net . IPAddress . IsLoopback ( address ) )
return true ;
var host = System . Net . Dns . GetHostName ( ) ;
var addrs = System . Net . Dns . GetHostAddresses ( host ) ;
foreach ( var addr in addrs )
if ( address . Equals ( addr ) )
return true ;
return false ;
}
2012-10-22 13:58:43 +08:00
/// <summary>
/// Determines whether the specified object is <see langword="null"/>.
/// </summary>
/// <returns>
2012-12-05 21:10:15 +08:00
/// <c>true</c> if the <paramref name="obj"/> parameter is <see langword="null"/>; otherwise, <c>false</c>.
2012-10-22 13:58:43 +08:00
/// </returns>
/// <param name="obj">
2013-01-11 19:32:38 +08:00
/// A <b>class</b> to test.
2012-10-22 13:58:43 +08:00
/// </param>
/// <typeparam name="T">
2012-12-05 21:10:15 +08:00
/// The type of the <paramref name="obj"/> parameter.
2012-10-22 13:58:43 +08:00
/// </typeparam>
public static bool IsNull < T > ( this T obj )
where T : class
{
return obj = = null ? true : false ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Determines whether the specified object is <see langword="null"/>.
/// And invokes the specified <see cref="Action"/> delegate if the specified object is <see langword="null"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="obj"/> parameter is <see langword="null"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="obj">
2013-01-11 19:32:38 +08:00
/// A <b>class</b> to test.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
/// An <see cref="Action"/> delegate that contains the method(s) called if the <paramref name="obj"/> is <see langword="null"/>.
/// </param>
/// <typeparam name="T">
/// The type of the <paramref name="obj"/> parameter.
/// </typeparam>
2012-10-22 13:58:43 +08:00
public static bool IsNullDo < T > ( this T obj , Action act )
2012-07-31 09:36:52 +08:00
where T : class
{
2012-10-22 13:58:43 +08:00
if ( obj . IsNull ( ) )
2012-07-31 09:36:52 +08:00
{
act ( ) ;
return true ;
}
return false ;
}
2012-10-22 13:58:43 +08:00
/// <summary>
/// Determines whether the specified <see cref="string"/> is <see langword="null"/> or <see cref="String.Empty"/>.
/// </summary>
/// <returns>
2012-12-05 21:10:15 +08:00
/// <c>true</c> if the <paramref name="value"/> parameter is <see langword="null"/> or <see cref="String.Empty"/>; otherwise, <c>false</c>.
2012-10-22 13:58:43 +08:00
/// </returns>
/// <param name="value">
/// A <see cref="string"/> to test.
/// </param>
public static bool IsNullOrEmpty ( this string value )
{
return String . IsNullOrEmpty ( value ) ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Determines whether the specified <see cref="string"/> is predefined scheme.
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="scheme"/> parameter is the predefined scheme; otherwise, <c>false</c>.
/// </returns>
/// <param name="scheme">
/// A <see cref="string"/> to test.
/// </param>
2012-09-10 00:36:22 +08:00
public static bool IsPredefinedScheme ( this string scheme )
{
2012-10-22 13:58:43 +08:00
if ( scheme . IsNull ( ) & & scheme . Length < 2 )
2012-09-10 00:36:22 +08:00
return false ;
char c = scheme [ 0 ] ;
if ( c = = 'h' )
return ( scheme = = "http" | | scheme = = "https" ) ;
if ( c = = 'f' )
return ( scheme = = "file" | | scheme = = "ftp" ) ;
2012-09-24 14:01:25 +08:00
if ( c = = 'w' )
return ( scheme = = "ws" | | scheme = = "wss" ) ;
2012-09-10 00:36:22 +08:00
if ( c = = 'n' )
{
c = scheme [ 1 ] ;
if ( c = = 'e' )
return ( scheme = = "news" | | scheme = = "net.pipe" | | scheme = = "net.tcp" ) ;
2012-12-05 21:10:15 +08:00
2012-09-10 00:36:22 +08:00
if ( scheme = = "nntp" )
return true ;
return false ;
}
if ( ( c = = 'g' & & scheme = = "gopher" ) | | ( c = = 'm' & & scheme = = "mailto" ) )
return true ;
return false ;
}
2013-02-18 15:47:33 +08:00
/// <summary>
/// Determines whether the specified <see cref="HttpListenerRequest"/> is the HTTP Upgrade request
/// to switch to the specified <paramref name="protocol"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the specified <see cref="HttpListenerRequest"/> is the HTTP Upgrade request
/// to switch to the specified <paramref name="protocol"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="request">
/// A <see cref="HttpListenerRequest"/> that contains an HTTP request information.
/// </param>
/// <param name="protocol">
/// A <see cref="string"/> that contains a protocol name.
/// </param>
/// <exception cref="ArgumentNullException">
/// <para>
/// <paramref name="request"/> is <see langword="null"/>.
/// </para>
/// <para>
/// -or-
/// </para>
/// <para>
/// <paramref name="protocol"/> is <see langword="null"/>.
/// </para>
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="protocol"/> is <see cref="String.Empty"/>.
/// </exception>
public static bool IsUpgradeTo ( this HttpListenerRequest request , string protocol )
{
if ( request . IsNull ( ) )
throw new ArgumentNullException ( "request" ) ;
if ( protocol . IsNull ( ) )
throw new ArgumentNullException ( "protocol" ) ;
if ( protocol . IsEmpty ( ) )
throw new ArgumentException ( "Must not be empty." , "protocol" ) ;
if ( ! request . Headers . Exists ( "Upgrade" , protocol ) )
return false ;
if ( ! request . Headers . Exists ( "Connection" , "Upgrade" ) )
return false ;
return true ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Determines whether the specified <see cref="string"/> is valid absolute path.
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="absPath"/> parameter is valid absolute path; otherwise, <c>false</c>.
/// </returns>
/// <param name="absPath">
/// A <see cref="string"/> to test.
/// </param>
/// <param name="message">
/// A <see cref="string"/> that receives a message if the <paramref name="absPath"/> is invalid.
/// </param>
public static bool IsValidAbsolutePath ( this string absPath , out string message )
{
if ( absPath . IsNullOrEmpty ( ) )
{
message = "Must not be null or empty." ;
return false ;
}
var i = absPath . IndexOf ( '/' ) ;
if ( i ! = 0 )
{
message = "Not absolute path: " + absPath ;
return false ;
}
i = absPath . IndexOfAny ( new [ ] { '?' , '#' } ) ;
if ( i ! = - 1 )
{
message = "Must not contain either or both query and fragment components: " + absPath ;
return false ;
}
message = String . Empty ;
return true ;
}
/// <summary>
/// Determines whether the specified <see cref="string"/> is a URI string.
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="uriString"/> parameter is maybe a URI string; otherwise, <c>false</c>.
/// </returns>
/// <param name="uriString">
/// A <see cref="string"/> to test.
/// </param>
2012-09-24 14:01:25 +08:00
public static bool MaybeUri ( this string uriString )
{
2012-12-05 21:10:15 +08:00
if ( uriString . IsNullOrEmpty ( ) )
return false ;
2012-09-24 14:01:25 +08:00
int p = uriString . IndexOf ( ':' ) ;
if ( p = = - 1 )
return false ;
if ( p > = 10 )
return false ;
return uriString . Substring ( 0 , p ) . IsPredefinedScheme ( ) ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Determines whether two specified <see cref="string"/> objects don't have the same value.
/// </summary>
/// <returns>
/// <c>true</c> if the value of <paramref name="expected"/> parameter isn't the same as the value of <paramref name="actual"/> parameter; otherwise, <c>false</c>.
/// </returns>
/// <param name="expected">
/// The first <see cref="string"/> to compare.
/// </param>
/// <param name="actual">
/// The second <see cref="string"/> to compare.
/// </param>
/// <param name="ignoreCase">
/// A <see cref="bool"/> that indicates a case-sensitive or insensitive comparison. (<c>true</c> indicates a case-insensitive comparison.)
/// </param>
2012-10-23 14:39:31 +08:00
public static bool NotEqual ( this string expected , string actual , bool ignoreCase )
2010-11-09 21:06:20 +08:00
{
2012-10-23 14:39:31 +08:00
return String . Compare ( expected , actual , ignoreCase ) ! = 0
? true
: false ;
2010-11-09 21:06:20 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Reads a block of bytes from the specified stream and returns the read data in an array of <see cref="byte"/>.
/// </summary>
/// <returns>
/// An array of <see cref="byte"/> that receives the read data.
/// </returns>
/// <param name="stream">
/// A <see cref="Stream"/> that contains the data to read.
/// </param>
/// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to read.
/// </param>
2012-09-27 14:27:09 +08:00
public static byte [ ] ReadBytes ( this Stream stream , int length )
2010-10-18 21:28:56 +08:00
{
2012-12-05 21:10:15 +08:00
if ( stream . IsNull ( ) | | length < = 0 )
2012-10-01 14:26:31 +08:00
return new byte [ ] { } ;
2012-10-04 14:04:21 +08:00
var buffer = new byte [ length ] ;
var readLen = stream . Read ( buffer , 0 , length ) ;
2012-12-05 21:10:15 +08:00
return readLen = = length
? buffer
: readLen > 0
? buffer . SubArray ( 0 , readLen )
: new byte [ ] { } ;
2012-09-27 14:27:09 +08:00
}
2010-10-25 19:56:26 +08:00
2012-12-05 21:10:15 +08:00
/// <summary>
/// Reads a block of bytes from the specified stream and returns the read data in an array of <see cref="byte"/>.
/// </summary>
/// <returns>
/// An array of <see cref="byte"/> that receives the read data.
/// </returns>
/// <param name="stream">
/// A <see cref="Stream"/> that contains the data to read.
/// </param>
/// <param name="length">
/// A <see cref="long"/> that contains the number of bytes to read.
/// </param>
public static byte [ ] ReadBytes ( this Stream stream , long length )
{
return stream . ReadBytes ( length , 1024 ) ;
}
/// <summary>
/// Reads a block of bytes from the specified stream and returns the read data in an array of <see cref="byte"/>.
/// </summary>
/// <returns>
/// An array of <see cref="byte"/> that receives the read data.
/// </returns>
/// <param name="stream">
/// A <see cref="Stream"/> that contains the data to read.
/// </param>
/// <param name="length">
/// A <see cref="long"/> that contains the number of bytes to read.
/// </param>
/// <param name="bufferLength">
/// An <see cref="int"/> that contains the buffer size in bytes of each internal read.
/// </param>
2012-09-27 14:27:09 +08:00
public static byte [ ] ReadBytes ( this Stream stream , long length , int bufferLength )
{
2012-12-05 21:10:15 +08:00
if ( stream . IsNull ( ) | | length < = 0 )
return new byte [ ] { } ;
if ( bufferLength < = 0 )
bufferLength = 1024 ;
2012-10-04 14:04:21 +08:00
var count = length / bufferLength ;
var rem = length % bufferLength ;
var readData = new List < byte > ( ) ;
var readBuffer = new byte [ bufferLength ] ;
long readLen = 0 ;
var tmpLen = 0 ;
Action < byte [ ] > read = ( buffer ) = >
{
tmpLen = stream . Read ( buffer , 0 , buffer . Length ) ;
if ( tmpLen > 0 )
{
readLen + = tmpLen ;
readData . AddRange ( buffer . SubArray ( 0 , tmpLen ) ) ;
}
} ;
2010-10-25 19:56:26 +08:00
2012-07-31 09:36:52 +08:00
count . Times ( ( ) = >
{
2012-10-04 14:04:21 +08:00
read ( readBuffer ) ;
2012-07-31 09:36:52 +08:00
} ) ;
2012-09-27 14:27:09 +08:00
if ( rem > 0 )
2012-12-05 21:10:15 +08:00
read ( new byte [ rem ] ) ;
2012-07-31 09:36:52 +08:00
2012-12-05 21:10:15 +08:00
return readLen > 0
2012-10-04 14:04:21 +08:00
? readData . ToArray ( )
2012-12-05 21:10:15 +08:00
: new byte [ ] { } ;
2010-10-25 19:56:26 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Retrieves a sub-array from the specified <paramref name="array"/>. A sub-array starts at the specified element position.
/// </summary>
/// <returns>
/// An array of T that receives a sub-array, or an empty array of T if any problems with the parameters.
/// </returns>
/// <param name="array">
/// An array of T that contains the data to retrieve a sub-array.
/// </param>
/// <param name="startIndex">
/// An <see cref="int"/> that contains the zero-based starting position of a sub-array in the <paramref name="array"/>.
/// </param>
/// <param name="length">
/// An <see cref="int"/> that contains the number of elements to retrieve a sub-array.
/// </param>
/// <typeparam name="T">
/// The type of elements in the <paramref name="array"/>.
/// </typeparam>
2012-07-31 09:36:52 +08:00
public static T [ ] SubArray < T > ( this T [ ] array , int startIndex , int length )
2010-10-26 20:30:58 +08:00
{
2012-12-05 21:10:15 +08:00
if ( array . IsNull ( ) | | array . Length = = 0 )
return new T [ ] { } ;
if ( startIndex < 0 | | length < = 0 )
return new T [ ] { } ;
if ( startIndex + length > array . Length )
return new T [ ] { } ;
2012-07-31 09:36:52 +08:00
if ( startIndex = = 0 & & array . Length = = length )
return array ;
T [ ] subArray = new T [ length ] ;
2012-10-22 13:58:43 +08:00
Array . Copy ( array , startIndex , subArray , 0 , length ) ;
2012-07-31 09:36:52 +08:00
return subArray ;
2010-10-26 20:30:58 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Executes the specified <see cref="Action"/> delegate <paramref name="n"/> times.
/// </summary>
/// <param name="n">
2013-03-19 18:45:50 +08:00
/// An <see cref="int"/> is the number of times to execute.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
2013-03-19 18:45:50 +08:00
/// An <see cref="Action"/> delegate that references the method(s) to execute.
2012-12-05 21:10:15 +08:00
/// </param>
2012-09-03 10:55:52 +08:00
public static void Times ( this int n , Action act )
2010-10-25 19:56:26 +08:00
{
2012-12-05 21:10:15 +08:00
if ( n > 0 & & ! act . IsNull ( ) )
( ( ulong ) n ) . times ( act ) ;
2012-09-03 10:55:52 +08:00
}
2010-10-25 19:56:26 +08:00
2012-12-05 21:10:15 +08:00
/// <summary>
/// Executes the specified <see cref="Action"/> delegate <paramref name="n"/> times.
/// </summary>
/// <param name="n">
2013-03-19 18:45:50 +08:00
/// A <see cref="long"/> is the number of times to execute.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
2013-03-19 18:45:50 +08:00
/// An <see cref="Action"/> delegate that references the method(s) to execute.
2012-12-05 21:10:15 +08:00
/// </param>
public static void Times ( this long n , Action act )
2012-09-03 10:55:52 +08:00
{
2012-12-05 21:10:15 +08:00
if ( n > 0 & & ! act . IsNull ( ) )
( ( ulong ) n ) . times ( act ) ;
2012-09-03 10:55:52 +08:00
}
2010-10-25 19:56:26 +08:00
2012-12-05 21:10:15 +08:00
/// <summary>
/// Executes the specified <see cref="Action"/> delegate <paramref name="n"/> times.
/// </summary>
/// <param name="n">
2013-03-19 18:45:50 +08:00
/// A <see cref="uint"/> is the number of times to execute.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
2013-03-19 18:45:50 +08:00
/// An <see cref="Action"/> delegate that references the method(s) to execute.
2012-12-05 21:10:15 +08:00
/// </param>
public static void Times ( this uint n , Action act )
2012-09-27 14:27:09 +08:00
{
2012-12-05 21:10:15 +08:00
if ( n > 0 & & ! act . IsNull ( ) )
( ( ulong ) n ) . times ( act ) ;
2012-09-27 14:27:09 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Executes the specified <see cref="Action"/> delegate <paramref name="n"/> times.
/// </summary>
/// <param name="n">
2013-03-19 18:45:50 +08:00
/// A <see cref="ulong"/> is the number of times to execute.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
2013-03-19 18:45:50 +08:00
/// An <see cref="Action"/> delegate that references the method(s) to execute.
2012-12-05 21:10:15 +08:00
/// </param>
2012-09-03 10:55:52 +08:00
public static void Times ( this ulong n , Action act )
{
2012-12-05 21:10:15 +08:00
if ( n > 0 & & ! act . IsNull ( ) )
n . times ( act ) ;
2012-07-31 09:36:52 +08:00
}
2010-10-25 19:56:26 +08:00
2012-12-05 21:10:15 +08:00
/// <summary>
2013-03-19 18:45:50 +08:00
/// Executes the specified <b>Action<int></b> delegate <paramref name="n"/> times.
2012-12-05 21:10:15 +08:00
/// </summary>
/// <param name="n">
2013-03-19 18:45:50 +08:00
/// An <see cref="int"/> is the number of times to execute.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
2013-03-19 18:45:50 +08:00
/// An <b>Action<int></b> delegate that references the method(s) to execute.
/// An <see cref="int"/> parameter to pass to the method(s) is the zero-based count of iteration.
2012-12-05 21:10:15 +08:00
/// </param>
2013-03-19 18:45:50 +08:00
public static void Times ( this int n , Action < int > act )
2012-07-31 09:36:52 +08:00
{
2012-12-05 21:10:15 +08:00
if ( n > 0 & & ! act . IsNull ( ) )
2013-03-19 18:45:50 +08:00
for ( int i = 0 ; i < n ; i + + )
act ( i ) ;
2012-09-03 10:55:52 +08:00
}
2010-10-25 19:56:26 +08:00
2012-12-05 21:10:15 +08:00
/// <summary>
2013-03-19 18:45:50 +08:00
/// Executes the specified <b>Action<long></b> delegate <paramref name="n"/> times.
2012-12-05 21:10:15 +08:00
/// </summary>
/// <param name="n">
2013-03-19 18:45:50 +08:00
/// A <see cref="long"/> is the number of times to execute.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
2013-03-19 18:45:50 +08:00
/// An <b>Action<long></b> delegate that references the method(s) to execute.
/// A <see cref="long"/> parameter to pass to the method(s) is the zero-based count of iteration.
2012-12-05 21:10:15 +08:00
/// </param>
2013-03-19 18:45:50 +08:00
public static void Times ( this long n , Action < long > act )
2012-09-03 10:55:52 +08:00
{
2012-12-05 21:10:15 +08:00
if ( n > 0 & & ! act . IsNull ( ) )
2013-03-19 18:45:50 +08:00
for ( long i = 0 ; i < n ; i + + )
act ( i ) ;
2012-09-03 10:55:52 +08:00
}
2012-07-31 09:36:52 +08:00
2012-12-05 21:10:15 +08:00
/// <summary>
2013-03-19 18:45:50 +08:00
/// Executes the specified <b>Action<uint></b> delegate <paramref name="n"/> times.
2012-12-05 21:10:15 +08:00
/// </summary>
/// <param name="n">
2013-03-19 18:45:50 +08:00
/// A <see cref="uint"/> is the number of times to execute.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
2013-03-19 18:45:50 +08:00
/// An <b>Action<uint></b> delegate that references the method(s) to execute.
/// A <see cref="uint"/> parameter to pass to the method(s) is the zero-based count of iteration.
2012-12-05 21:10:15 +08:00
/// </param>
2013-03-19 18:45:50 +08:00
public static void Times ( this uint n , Action < uint > act )
2012-09-27 14:27:09 +08:00
{
2012-12-05 21:10:15 +08:00
if ( n > 0 & & ! act . IsNull ( ) )
2013-03-19 18:45:50 +08:00
for ( uint i = 0 ; i < n ; i + + )
act ( i ) ;
2012-09-27 14:27:09 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
2013-01-11 19:32:38 +08:00
/// Executes the specified <b>Action<ulong></b> delegate <paramref name="n"/> times.
2012-12-05 21:10:15 +08:00
/// </summary>
/// <param name="n">
2013-03-19 18:45:50 +08:00
/// A <see cref="ulong"/> is the number of times to execute.
2012-12-05 21:10:15 +08:00
/// </param>
/// <param name="act">
2013-03-19 18:45:50 +08:00
/// An <b>Action<ulong></b> delegate that references the method(s) to execute.
/// A <see cref="ulong"/> parameter to pass to this method(s) is the zero-based count of iteration.
2012-12-05 21:10:15 +08:00
/// </param>
2012-09-03 10:55:52 +08:00
public static void Times ( this ulong n , Action < ulong > act )
{
2012-12-05 21:10:15 +08:00
if ( n > 0 & & ! act . IsNull ( ) )
2013-03-19 18:45:50 +08:00
for ( ulong i = 0 ; i < n ; i + + )
act ( i ) ;
2010-10-25 19:56:26 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Converts the specified array of <see cref="byte"/> to the specified type data.
/// </summary>
/// <returns>
/// A T converted from the <paramref name="src"/>, or a default value of T
/// if the <paramref name="src"/> is an empty array of <see cref="byte"/>
/// or if the types of T aren't the <see cref="bool"/>, <see cref="char"/>, <see cref="double"/>,
/// <see cref="float"/>, <see cref="int"/>, <see cref="long"/>, <see cref="short"/>,
/// <see cref="uint"/>, <see cref="ulong"/>, <see cref="ushort"/>.
/// </returns>
/// <param name="src">
/// An array of <see cref="byte"/> to convert.
/// </param>
/// <param name="srcOrder">
/// A <see cref="WebSocketSharp.ByteOrder"/> that indicates the byte order of the <paramref name="src"/>.
/// </param>
/// <typeparam name="T">
/// The type of the return value. The T must be a value type.
/// </typeparam>
/// <exception cref="ArgumentNullException">
/// Is thrown when the <paramref name="src"/> parameter passed to a method is invalid because it is <see langword="null"/>.
/// </exception>
2012-07-31 09:36:52 +08:00
public static T To < T > ( this byte [ ] src , ByteOrder srcOrder )
where T : struct
2010-10-25 19:56:26 +08:00
{
2012-12-05 21:10:15 +08:00
if ( src . IsNull ( ) )
throw new ArgumentNullException ( "src" ) ;
2012-07-31 09:36:52 +08:00
2012-12-05 21:10:15 +08:00
if ( src . Length = = 0 )
return default ( T ) ;
var type = typeof ( T ) ;
var buffer = src . ToHostOrder ( srcOrder ) ;
if ( type = = typeof ( Boolean ) )
return ( T ) ( object ) BitConverter . ToBoolean ( buffer , 0 ) ;
if ( type = = typeof ( Char ) )
return ( T ) ( object ) BitConverter . ToChar ( buffer , 0 ) ;
if ( type = = typeof ( Double ) )
return ( T ) ( object ) BitConverter . ToDouble ( buffer , 0 ) ;
if ( type = = typeof ( Int16 ) )
return ( T ) ( object ) BitConverter . ToInt16 ( buffer , 0 ) ;
if ( type = = typeof ( Int32 ) )
return ( T ) ( object ) BitConverter . ToInt32 ( buffer , 0 ) ;
if ( type = = typeof ( Int64 ) )
return ( T ) ( object ) BitConverter . ToInt64 ( buffer , 0 ) ;
if ( type = = typeof ( Single ) )
return ( T ) ( object ) BitConverter . ToSingle ( buffer , 0 ) ;
2012-07-31 09:36:52 +08:00
2012-12-05 21:10:15 +08:00
if ( type = = typeof ( UInt16 ) )
return ( T ) ( object ) BitConverter . ToUInt16 ( buffer , 0 ) ;
if ( type = = typeof ( UInt32 ) )
return ( T ) ( object ) BitConverter . ToUInt32 ( buffer , 0 ) ;
if ( type = = typeof ( UInt64 ) )
return ( T ) ( object ) BitConverter . ToUInt64 ( buffer , 0 ) ;
return default ( T ) ;
2010-10-25 19:56:26 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Converts the specified data to an array of <see cref="byte"/>.
/// </summary>
/// <returns>
/// An array of <see cref="byte"/> converted from the <paramref name="value"/>.
/// </returns>
/// <param name="value">
/// A T to convert.
/// </param>
/// <param name="order">
/// A <see cref="WebSocketSharp.ByteOrder"/> that indicates the byte order of the return.
/// </param>
/// <typeparam name="T">
/// The type of the <paramref name="value"/>. The T must be a value type.
/// </typeparam>
2012-07-31 09:36:52 +08:00
public static byte [ ] ToBytes < T > ( this T value , ByteOrder order )
where T : struct
2010-10-18 21:28:56 +08:00
{
2012-12-05 21:10:15 +08:00
var type = typeof ( T ) ;
2012-07-31 09:36:52 +08:00
byte [ ] buffer ;
2012-12-05 21:10:15 +08:00
if ( type = = typeof ( Boolean ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( Boolean ) ( object ) value ) ;
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( Char ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( Char ) ( object ) value ) ;
2010-10-28 00:35:25 +08:00
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( Double ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( Double ) ( object ) value ) ;
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( Int16 ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( Int16 ) ( object ) value ) ;
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( Int32 ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( Int32 ) ( object ) value ) ;
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( Int64 ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( Int64 ) ( object ) value ) ;
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( Single ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( Single ) ( object ) value ) ;
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( UInt16 ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( UInt16 ) ( object ) value ) ;
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( UInt32 ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( UInt32 ) ( object ) value ) ;
}
2012-12-05 21:10:15 +08:00
else if ( type = = typeof ( UInt64 ) )
2012-07-31 09:36:52 +08:00
{
buffer = BitConverter . GetBytes ( ( UInt64 ) ( object ) value ) ;
}
else
{
buffer = new byte [ ] { } ;
}
2012-12-05 21:10:15 +08:00
return buffer . Length = = 0 | | order . IsHostOrder ( )
2012-07-31 09:36:52 +08:00
? buffer
: buffer . Reverse ( ) . ToArray ( ) ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Converts the order of the specified array of <see cref="byte"/> to the host byte order.
/// </summary>
/// <returns>
/// An array of <see cref="byte"/> converted from the <paramref name="src"/>.
/// </returns>
/// <param name="src">
/// An array of <see cref="byte"/> to convert.
/// </param>
/// <param name="srcOrder">
/// A <see cref="WebSocketSharp.ByteOrder"/> that indicates the byte order of the <paramref name="src"/>.
/// </param>
/// <exception cref="ArgumentNullException">
/// Is thrown when the <paramref name="src"/> parameter passed to a method is invalid because it is <see langword="null"/>.
/// </exception>
2012-07-31 09:36:52 +08:00
public static byte [ ] ToHostOrder ( this byte [ ] src , ByteOrder srcOrder )
{
2012-12-05 21:10:15 +08:00
if ( src . IsNull ( ) )
throw new ArgumentNullException ( "src" ) ;
2010-11-09 21:06:20 +08:00
2012-12-05 21:10:15 +08:00
return src . Length = = 0 | | srcOrder . IsHostOrder ( )
? src
: src . Reverse ( ) . ToArray ( ) ;
2010-10-28 00:35:25 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Converts the specified array to a <see cref="string"/> concatenated the specified separator string
/// between each element of this array.
/// </summary>
/// <returns>
/// A <see cref="string"/> converted from the <paramref name="array"/> parameter, or a <see cref="String.Empty"/>
/// if the length of the <paramref name="array"/> is zero.
/// </returns>
/// <param name="array">
/// An array of T to convert.
/// </param>
/// <param name="separator">
/// A <see cref="string"/> that contains a separator string.
/// </param>
/// <typeparam name="T">
/// The type of elements in the <paramref name="array"/>.
/// </typeparam>
/// <exception cref="ArgumentNullException">
/// Is thrown when the <paramref name="array"/> parameter passed to a method is invalid because it is <see langword="null"/>.
/// </exception>
public static string ToString < T > ( this T [ ] array , string separator )
2010-10-28 00:35:25 +08:00
{
2012-12-05 21:10:15 +08:00
if ( array . IsNull ( ) )
throw new ArgumentNullException ( "array" ) ;
2012-10-12 13:53:29 +08:00
var len = array . Length ;
2012-07-31 09:36:52 +08:00
if ( len = = 0 )
return String . Empty ;
2012-12-05 21:10:15 +08:00
if ( separator . IsNull ( ) )
separator = String . Empty ;
2012-10-12 13:53:29 +08:00
var sb = new StringBuilder ( ) ;
2012-12-05 21:10:15 +08:00
( len - 1 ) . Times ( i = >
sb . AppendFormat ( "{0}{1}" , array [ i ] . ToString ( ) , separator )
) ;
2012-07-31 09:36:52 +08:00
2012-12-05 21:10:15 +08:00
sb . Append ( array [ len - 1 ] . ToString ( ) ) ;
2012-07-31 09:36:52 +08:00
return sb . ToString ( ) ;
2010-10-18 21:28:56 +08:00
}
2012-09-10 00:36:22 +08:00
2012-12-05 21:10:15 +08:00
/// <summary>
/// Converts the specified <see cref="string"/> to a <see cref="Uri"/> object.
/// </summary>
/// <returns>
/// A <see cref="Uri"/> converted from the <paramref name="uriString"/> parameter, or <see langword="null"/>
/// if the <paramref name="uriString"/> is <see langword="null"/> or <see cref="String.Empty"/>.
/// </returns>
/// <param name="uriString">
/// A <see cref="string"/> to convert.
/// </param>
2012-09-10 00:36:22 +08:00
public static Uri ToUri ( this string uriString )
{
2012-12-05 21:10:15 +08:00
return uriString . IsNullOrEmpty ( )
? null
: uriString . MaybeUri ( )
? new Uri ( uriString )
: new Uri ( uriString , UriKind . Relative ) ;
2012-09-10 00:36:22 +08:00
}
2012-10-22 13:58:43 +08:00
/// <summary>
2012-12-05 21:10:15 +08:00
/// Tries to create a new WebSocket <see cref="Uri"/> using the specified <paramref name="uriString"/>.
2012-10-22 13:58:43 +08:00
/// </summary>
/// <returns>
/// <c>true</c> if the WebSocket <see cref="Uri"/> was successfully created; otherwise, <c>false</c>.
/// </returns>
/// <param name="uriString">
/// A <see cref="string"/> that contains a WebSocket URI.
/// </param>
/// <param name="result">
2012-12-05 21:10:15 +08:00
/// When this method returns, contains a created WebSocket <see cref="Uri"/> if the <paramref name="uriString"/> parameter is valid WebSocket URI; otherwise, <see langword="null"/>.
2012-10-22 13:58:43 +08:00
/// </param>
/// <param name="message">
2012-12-05 21:10:15 +08:00
/// When this method returns, contains a error message <see cref="string"/> if the <paramref name="uriString"/> parameter is invalid WebSocket URI; otherwise, <c>String.Empty</c>.
2012-10-22 13:58:43 +08:00
/// </param>
/// <exception cref="ArgumentNullException">
2012-12-05 21:10:15 +08:00
/// Is thrown when the <paramref name="uriString"/> parameter passed to a method is invalid because it is <see langword="null"/>.
2012-10-22 13:58:43 +08:00
/// </exception>
public static bool TryCreateWebSocketUri ( this string uriString , out Uri result , out string message )
{
2013-03-02 15:34:38 +08:00
if ( uriString . IsNull ( ) )
2012-10-22 13:58:43 +08:00
throw new ArgumentNullException ( "uriString" ) ;
result = null ;
2013-03-02 15:34:38 +08:00
if ( uriString . IsEmpty ( ) )
2012-10-22 13:58:43 +08:00
{
message = "Must not be empty." ;
return false ;
}
var uri = uriString . ToUri ( ) ;
if ( ! uri . IsAbsoluteUri )
{
message = "Not absolute URI: " + uriString ;
return false ;
}
var scheme = uri . Scheme ;
if ( scheme ! = "ws" & & scheme ! = "wss" )
{
message = "Unsupported scheme: " + scheme ;
return false ;
}
var fragment = uri . Fragment ;
if ( ! String . IsNullOrEmpty ( fragment ) )
{
message = "Must not contain the fragment component: " + uriString ;
return false ;
}
var port = uri . Port ;
if ( port > 0 )
{
if ( ( scheme = = "ws" & & port = = 443 ) | |
( scheme = = "wss" & & port = = 80 ) )
{
message = String . Format (
"Invalid pair of scheme and port: {0}, {1}" , scheme , port ) ;
return false ;
}
}
2013-03-02 15:34:38 +08:00
else
{
port = scheme = = "ws"
? 80
: 443 ;
var url = String . Format ( "{0}://{1}:{2}{3}" , scheme , uri . Host , port , uri . PathAndQuery ) ;
uri = url . ToUri ( ) ;
}
2012-10-22 13:58:43 +08:00
result = uri ;
message = String . Empty ;
return true ;
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// URL-decodes the specified <see cref="string"/>.
/// </summary>
/// <returns>
/// A <see cref="string"/> that receives a decoded string, or the <paramref name="s"/> parameter
/// if the <paramref name="s"/> is <see langword="null"/> or <see cref="String.Empty"/>.
/// </returns>
/// <param name="s">
/// A <see cref="string"/> to decode.
/// </param>
2012-10-22 13:58:43 +08:00
public static string UrlDecode ( this string s )
{
2012-12-05 21:10:15 +08:00
return s . IsNullOrEmpty ( )
? s
: HttpUtility . UrlDecode ( s ) ;
2012-10-22 13:58:43 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// URL-encodes the specified <see cref="string"/>.
/// </summary>
/// <returns>
/// A <see cref="string"/> that receives a encoded string, or the <paramref name="s"/> parameter
/// if the <paramref name="s"/> is <see langword="null"/> or <see cref="String.Empty"/>.
/// </returns>
/// <param name="s">
/// A <see cref="string"/> to encode.
/// </param>
2012-10-22 13:58:43 +08:00
public static string UrlEncode ( this string s )
{
2012-12-05 21:10:15 +08:00
return s . IsNullOrEmpty ( )
? s
: HttpUtility . UrlEncode ( s ) ;
2012-10-22 13:58:43 +08:00
}
2012-12-05 21:10:15 +08:00
/// <summary>
/// Writes the specified content data using the specified <see cref="WebSocketSharp.Net.HttpListenerResponse"/>.
/// </summary>
/// <param name="response">
/// A <see cref="WebSocketSharp.Net.HttpListenerResponse"/> that contains a network stream to write a content data.
/// </param>
/// <param name="content">
/// An array of <see cref="byte"/> that contains a content data to write.
/// </param>
/// <exception cref="ArgumentNullException">
/// Is thrown when the <paramref name="response"/> parameter passed to a method is invalid because it is <see langword="null"/>.
/// </exception>
2012-10-01 14:26:31 +08:00
public static void WriteContent ( this HttpListenerResponse response , byte [ ] content )
2012-09-10 00:36:22 +08:00
{
2012-12-05 21:10:15 +08:00
if ( response . IsNull ( ) )
throw new ArgumentNullException ( "response" ) ;
if ( content . IsNull ( ) | | content . Length = = 0 )
return ;
2012-09-10 00:36:22 +08:00
var output = response . OutputStream ;
response . ContentLength64 = content . Length ;
output . Write ( content , 0 , content . Length ) ;
output . Close ( ) ;
}
2012-12-05 21:10:15 +08:00
#endregion
2010-10-18 21:28:56 +08:00
}
}