2021-02-19 16:50:05 +01:00
// Copyright (c) Umbraco.
2021-02-18 11:06:02 +01:00
// See LICENSE for more details.
2019-05-20 17:57:28 +02:00
using System.ComponentModel ;
2024-11-25 13:55:40 +01:00
using System.ComponentModel.DataAnnotations ;
2019-05-20 17:57:28 +02:00
using System.Diagnostics.CodeAnalysis ;
using System.Globalization ;
using System.Security.Cryptography ;
using System.Text ;
using System.Text.RegularExpressions ;
2021-02-18 11:06:02 +01:00
using Umbraco.Cms.Core ;
using Umbraco.Cms.Core.Strings ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
namespace Umbraco.Extensions ;
/// <summary>
/// String extension methods
/// </summary>
public static class StringExtensions
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
internal static readonly Lazy < Regex > Whitespace = new ( ( ) = > new Regex ( @"\s+" , RegexOptions . Compiled ) ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
private const char DefaultEscapedStringEscapeChar = '\\' ;
private static readonly char [ ] ToCSharpHexDigitLower = "0123456789abcdef" . ToCharArray ( ) ;
private static readonly char [ ] ToCSharpEscapeChars ;
internal static readonly string [ ] JsonEmpties = { "[]" , "{}" } ;
/// <summary>
/// The namespace for URLs (from RFC 4122, Appendix C).
/// See <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>
/// </summary>
internal static readonly Guid UrlNamespace = new ( "6ba7b811-9dad-11d1-80b4-00c04fd430c8" ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
private static readonly char [ ] CleanForXssChars = "*?(){}[];:%<>/\\|&'\"" . ToCharArray ( ) ;
// From: http://stackoverflow.com/a/961504/5018
// filters control characters but allows only properly-formed surrogate sequences
private static readonly Lazy < Regex > InvalidXmlChars = new ( ( ) = >
new Regex (
@"(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\uFEFF\uFFFE\uFFFF]" ,
RegexOptions . Compiled ) ) ;
static StringExtensions ( )
{
var escapes = new [ ] { "\aa" , "\bb" , "\ff" , "\nn" , "\rr" , "\tt" , "\vv" , "\"\"" , "\\\\" , "??" , "\00" } ;
ToCSharpEscapeChars = new char [ escapes . Max ( e = > e [ 0 ] ) + 1 ] ;
foreach ( var escape in escapes )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
ToCSharpEscapeChars [ escape [ 0 ] ] = escape [ 1 ] ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Convert a path to node ids in the order from right to left (deepest to shallowest)
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static int [ ] GetIdsFromPathReversed ( this string path )
{
var nodeIds = path . Split ( Constants . CharArrays . Comma , StringSplitOptions . RemoveEmptyEntries )
. Select ( x = >
int . TryParse ( x , NumberStyles . Integer , CultureInfo . InvariantCulture , out var output )
? Attempt < int > . Succeed ( output )
: Attempt < int > . Fail ( ) )
. Where ( x = > x . Success )
. Select ( x = > x . Result )
. Reverse ( )
. ToArray ( ) ;
return nodeIds ;
}
/// <summary>
/// Removes new lines and tabs
/// </summary>
/// <param name="txt"></param>
/// <returns></returns>
public static string StripWhitespace ( this string txt ) = > Regex . Replace ( txt , @"\s" , string . Empty ) ;
public static string StripFileExtension ( this string fileName )
{
// filenames cannot contain line breaks
if ( fileName . Contains ( Environment . NewLine ) | | fileName . Contains ( "\r" ) | | fileName . Contains ( "\n" ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return fileName ;
2019-05-20 17:57:28 +02:00
}
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
ReadOnlySpan < char > spanFileName = fileName . AsSpan ( ) ;
2022-11-28 22:12:30 +01:00
var lastIndex = spanFileName . LastIndexOf ( '.' ) ;
2022-06-07 15:28:38 +02:00
if ( lastIndex > 0 )
2019-05-20 17:57:28 +02:00
{
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
ReadOnlySpan < char > ext = spanFileName [ lastIndex . . ] ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// file extensions cannot contain whitespace
2022-11-28 22:12:30 +01:00
if ( ext . Contains ( ' ' ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return fileName ;
2019-05-20 17:57:28 +02:00
}
2022-11-28 22:12:30 +01:00
return new string ( spanFileName [ . . lastIndex ] ) ;
2022-06-07 15:28:38 +02:00
}
2018-06-29 19:52:40 +02:00
2022-06-07 15:28:38 +02:00
return fileName ;
}
2018-06-29 19:52:40 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Determines the extension of the path or URL
/// </summary>
/// <param name="file"></param>
/// <returns>Extension of the file</returns>
public static string GetFileExtension ( this string file )
{
// Find any characters between the last . and the start of a query string or the end of the string
const string pattern = @"(?<extension>\.[^\.\?]+)(\?.*|$)" ;
Match match = Regex . Match ( file , pattern ) ;
return match . Success
? match . Groups [ "extension" ] . Value
: string . Empty ;
}
2018-06-29 19:52:40 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// This tries to detect a json string, this is not a fail safe way but it is quicker than doing
/// a try/catch when deserializing when it is not json.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static bool DetectIsJson ( this string input )
{
if ( input . IsNullOrWhiteSpace ( ) )
2020-03-24 13:35:11 -04:00
{
2022-06-07 15:28:38 +02:00
return false ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
input = input . Trim ( ) ;
2022-10-05 12:14:43 +02:00
return ( input [ 0 ] is '[' & & input [ ^ 1 ] is ']' ) | | ( input [ 0 ] is '{' & & input [ ^ 1 ] is '}' ) ;
2022-06-07 15:28:38 +02:00
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
public static bool DetectIsEmptyJson ( this string input ) = >
JsonEmpties . Contains ( Whitespace . Value . Replace ( input , string . Empty ) ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
public static string ReplaceNonAlphanumericChars ( this string input , string replacement )
{
// any character that is not alphanumeric, convert to a hyphen
var mName = input ;
foreach ( var c in mName . ToCharArray ( ) . Where ( c = > ! char . IsLetterOrDigit ( c ) ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
mName = mName . Replace ( c . ToString ( CultureInfo . InvariantCulture ) , replacement ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return mName ;
}
public static string ReplaceNonAlphanumericChars ( this string input , char replacement )
{
var inputArray = input . ToCharArray ( ) ;
var outputArray = new char [ input . Length ] ;
for ( var i = 0 ; i < inputArray . Length ; i + + )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
outputArray [ i ] = char . IsLetterOrDigit ( inputArray [ i ] ) ? inputArray [ i ] : replacement ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return new string ( outputArray ) ;
}
/// <summary>
/// Cleans string to aid in preventing xss attacks.
/// </summary>
/// <param name="input"></param>
/// <param name="ignoreFromClean"></param>
/// <returns></returns>
public static string CleanForXss ( this string input , params char [ ] ignoreFromClean )
{
// remove any HTML
input = input . StripHtml ( ) ;
// strip out any potential chars involved with XSS
return input . ExceptChars ( new HashSet < char > ( CleanForXssChars . Except ( ignoreFromClean ) ) ) ;
}
public static string ExceptChars ( this string str , HashSet < char > toExclude )
{
var sb = new StringBuilder ( str . Length ) ;
foreach ( var c in str . Where ( c = > toExclude . Contains ( c ) = = false ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
sb . Append ( c ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return sb . ToString ( ) ;
}
/// <summary>
/// This will append the query string to the URL
/// </summary>
/// <param name="url"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
/// <remarks>
/// This methods ensures that the resulting URL is structured correctly, that there's only one '?' and that things are
2023-09-06 20:08:17 +02:00
/// delimited properly with '&'
2022-06-07 15:28:38 +02:00
/// </remarks>
public static string AppendQueryStringToUrl ( this string url , params string [ ] queryStrings )
{
// remove any prefixed '&' or '?'
for ( var i = 0 ; i < queryStrings . Length ; i + + )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
queryStrings [ i ] = queryStrings [ i ] . TrimStart ( Constants . CharArrays . QuestionMarkAmpersand )
. TrimEnd ( Constants . CharArrays . Ampersand ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
var nonEmpty = queryStrings . Where ( x = > ! x . IsNullOrWhiteSpace ( ) ) . ToArray ( ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
if ( url . Contains ( "?" ) )
{
return url + string . Join ( "&" , nonEmpty ) . EnsureStartsWith ( '&' ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return url + string . Join ( "&" , nonEmpty ) . EnsureStartsWith ( '?' ) ;
}
/// <summary>
/// Returns a stream from a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
internal static Stream GenerateStreamFromString ( this string s )
{
var stream = new MemoryStream ( ) ;
var writer = new StreamWriter ( stream ) ;
writer . Write ( s ) ;
writer . Flush ( ) ;
stream . Position = 0 ;
return stream ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// this is from SqlMetal and just makes it a bit of fun to allow pluralization
public static string MakePluralName ( this string name )
{
if ( name . EndsWith ( "x" , StringComparison . OrdinalIgnoreCase ) | |
name . EndsWith ( "ch" , StringComparison . OrdinalIgnoreCase ) | |
name . EndsWith ( "s" , StringComparison . OrdinalIgnoreCase ) | |
name . EndsWith ( "sh" , StringComparison . OrdinalIgnoreCase ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
name + = "es" ;
2019-05-20 17:57:28 +02:00
return name ;
}
2022-06-07 15:28:38 +02:00
if ( name . EndsWith ( "y" , StringComparison . OrdinalIgnoreCase ) & & name . Length > 1 & &
! IsVowel ( name [ ^ 2 ] ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
name = name . Remove ( name . Length - 1 , 1 ) ;
name + = "ies" ;
return name ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( ! name . EndsWith ( "s" , StringComparison . OrdinalIgnoreCase ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
name + = "s" ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return name ;
}
public static bool IsVowel ( this char c )
{
switch ( c )
{
case 'O' :
case 'U' :
case 'Y' :
case 'A' :
case 'E' :
case 'I' :
case 'o' :
case 'u' :
case 'y' :
case 'a' :
case 'e' :
case 'i' :
return true ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return false ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Trims the specified value from a string; accepts a string input whereas the in-built implementation only accepts
/// char or char[].
/// </summary>
/// <param name="value">The value.</param>
/// <param name="forRemoving">For removing.</param>
/// <returns></returns>
2024-11-13 09:27:29 +01:00
public static string Trim ( this string value , string forRemoving )
2022-06-07 15:28:38 +02:00
{
if ( string . IsNullOrEmpty ( value ) )
{
2019-05-20 17:57:28 +02:00
return value ;
}
2024-11-13 09:27:29 +01:00
return value . TrimEnd ( forRemoving ) . TrimStart ( forRemoving ) ;
2022-06-07 15:28:38 +02:00
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
public static string EncodeJsString ( this string s )
{
var sb = new StringBuilder ( ) ;
foreach ( var c in s )
{
switch ( c )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
case '\"' :
sb . Append ( "\\\"" ) ;
break ;
case '\\' :
sb . Append ( "\\\\" ) ;
break ;
case '\b' :
sb . Append ( "\\b" ) ;
break ;
case '\f' :
sb . Append ( "\\f" ) ;
break ;
case '\n' :
sb . Append ( "\\n" ) ;
break ;
case '\r' :
sb . Append ( "\\r" ) ;
break ;
case '\t' :
sb . Append ( "\\t" ) ;
break ;
default :
int i = c ;
if ( i < 32 | | i > 127 )
{
sb . AppendFormat ( "\\u{0:X04}" , i ) ;
}
else
{
sb . Append ( c ) ;
}
break ;
2019-05-20 17:57:28 +02:00
}
}
2022-06-07 15:28:38 +02:00
return sb . ToString ( ) ;
}
2024-11-13 09:27:29 +01:00
public static string TrimEnd ( this string value , string forRemoving )
2022-06-07 15:28:38 +02:00
{
if ( string . IsNullOrEmpty ( value ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return value ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( string . IsNullOrEmpty ( forRemoving ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return value ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
while ( value . EndsWith ( forRemoving , StringComparison . InvariantCultureIgnoreCase ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
value = value . Remove ( value . LastIndexOf ( forRemoving , StringComparison . InvariantCultureIgnoreCase ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return value ;
}
2024-11-13 09:27:29 +01:00
public static string TrimStart ( this string value , string forRemoving )
2022-06-07 15:28:38 +02:00
{
if ( string . IsNullOrEmpty ( value ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return value ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( string . IsNullOrEmpty ( forRemoving ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return value ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
while ( value . StartsWith ( forRemoving , StringComparison . InvariantCultureIgnoreCase ) )
2019-05-20 17:57:28 +02:00
{
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
value = value [ forRemoving . Length . . ] ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return value ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
public static string EnsureStartsWith ( this string input , string toStartWith )
{
if ( input . StartsWith ( toStartWith ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return input ;
2019-05-20 17:57:28 +02:00
}
2024-11-13 09:27:29 +01:00
return toStartWith + input . TrimStart ( toStartWith ) ;
2022-06-07 15:28:38 +02:00
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
public static string EnsureStartsWith ( this string input , char value ) = >
input . StartsWith ( value . ToString ( CultureInfo . InvariantCulture ) ) ? input : value + input ;
public static string EnsureEndsWith ( this string input , char value ) = >
input . EndsWith ( value . ToString ( CultureInfo . InvariantCulture ) ) ? input : input + value ;
public static string EnsureEndsWith ( this string input , string toEndWith ) = >
input . EndsWith ( toEndWith . ToString ( CultureInfo . InvariantCulture ) ) ? input : input + toEndWith ;
public static bool IsLowerCase ( this char ch ) = > ch . ToString ( CultureInfo . InvariantCulture ) = =
ch . ToString ( CultureInfo . InvariantCulture ) . ToLowerInvariant ( ) ;
public static bool IsUpperCase ( this char ch ) = > ch . ToString ( CultureInfo . InvariantCulture ) = =
ch . ToString ( CultureInfo . InvariantCulture ) . ToUpperInvariant ( ) ;
/// <summary>
/// Indicates whether a specified string is null, empty, or
/// consists only of white-space characters.
/// </summary>
/// <param name="value">The value to check.</param>
/// <returns>
/// Returns <see langword="true" /> if the value is null,
/// empty, or consists only of white-space characters, otherwise
/// returns <see langword="false" />.
/// </returns>
2022-10-05 12:14:43 +02:00
public static bool IsNullOrWhiteSpace ( [ NotNullWhen ( false ) ] this string? value ) = > string . IsNullOrWhiteSpace ( value ) ;
2023-11-14 11:16:12 +01:00
2022-09-16 01:14:23 +02:00
[return: NotNullIfNotNull("defaultValue")]
2022-06-07 15:28:38 +02:00
public static string? IfNullOrWhiteSpace ( this string? str , string? defaultValue ) = >
str . IsNullOrWhiteSpace ( ) ? defaultValue : str ;
/// <summary>The to delimited list.</summary>
/// <param name="list">The list.</param>
/// <param name="delimiter">The delimiter.</param>
/// <returns>the list</returns>
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Justification = "By design")]
public static IList < string > ToDelimitedList ( this string list , string delimiter = "," )
{
var delimiters = new [ ] { delimiter } ;
return ! list . IsNullOrWhiteSpace ( )
? list . Split ( delimiters , StringSplitOptions . RemoveEmptyEntries )
. Select ( i = > i . Trim ( ) )
. ToList ( )
: new List < string > ( ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>enum try parse.</summary>
/// <param name="strType">The str type.</param>
/// <param name="ignoreCase">The ignore case.</param>
/// <param name="result">The result.</param>
/// <typeparam name="T">The type</typeparam>
/// <returns>The enum try parse.</returns>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "By Design")]
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "By Design")]
public static bool EnumTryParse < T > ( this string strType , bool ignoreCase , out T ? result )
{
try
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
result = ( T ) Enum . Parse ( typeof ( T ) , strType , ignoreCase ) ;
return true ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
catch
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
result = default ;
return false ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Parse string to Enum
/// </summary>
/// <typeparam name="T">The enum type</typeparam>
/// <param name="strType">The string to parse</param>
/// <param name="ignoreCase">The ignore case</param>
/// <returns>The parsed enum</returns>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "By Design")]
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "By Design")]
public static T EnumParse < T > ( this string strType , bool ignoreCase ) = > ( T ) Enum . Parse ( typeof ( T ) , strType , ignoreCase ) ;
/// <summary>
/// Strips all HTML from a string.
/// </summary>
/// <param name="text">The text.</param>
/// <returns>Returns the string without any HTML tags.</returns>
public static string StripHtml ( this string text )
{
const string pattern = @"<(.|\n)*?>" ;
return Regex . Replace ( text , pattern , string . Empty , RegexOptions . Compiled ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Encodes as GUID.
/// </summary>
/// <param name="input">The input.</param>
/// <returns></returns>
public static Guid EncodeAsGuid ( this string input )
{
if ( string . IsNullOrWhiteSpace ( input ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( "input" ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
var convertToHex = input . ConvertToHex ( ) ;
var hexLength = convertToHex . Length < 32 ? convertToHex . Length : 32 ;
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
var hex = convertToHex [ . . hexLength ] . PadLeft ( 32 , '0' ) ;
2022-06-07 15:28:38 +02:00
Guid output = Guid . Empty ;
return Guid . TryParse ( hex , out output ) ? output : Guid . Empty ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Converts to hex.
/// </summary>
/// <param name="input">The input.</param>
/// <returns></returns>
public static string ConvertToHex ( this string input )
{
if ( string . IsNullOrEmpty ( input ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return string . Empty ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
var sb = new StringBuilder ( input . Length ) ;
foreach ( var c in input )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
sb . AppendFormat ( "{0:x2}" , Convert . ToUInt32 ( c ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return sb . ToString ( ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
public static string DecodeFromHex ( this string hexValue )
{
var strValue = string . Empty ;
while ( hexValue . Length > 0 )
2019-05-20 17:57:28 +02:00
{
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
strValue + = Convert . ToChar ( Convert . ToUInt32 ( hexValue [ . . 2 ] , 16 ) ) . ToString ( ) ;
hexValue = hexValue [ 2. . ] ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return strValue ;
}
/// <summary>
/// Encodes a string to a safe URL base64 string
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string ToUrlBase64 ( this string input )
{
if ( input = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( input ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( string . IsNullOrEmpty ( input ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return string . Empty ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
// return Convert.ToBase64String(bytes).Replace(".", "-").Replace("/", "_").Replace("=", ",");
var bytes = Encoding . UTF8 . GetBytes ( input ) ;
return UrlTokenEncode ( bytes ) ;
}
/// <summary>
/// Decodes a URL safe base64 string back
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string? FromUrlBase64 ( this string input )
{
if ( input = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( input ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
// if (input.IsInvalidBase64()) return null;
try
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
// var decodedBytes = Convert.FromBase64String(input.Replace("-", ".").Replace("_", "/").Replace(",", "="));
var decodedBytes = UrlTokenDecode ( input ) ;
return decodedBytes ! = null ? Encoding . UTF8 . GetString ( decodedBytes ) : null ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
catch ( FormatException )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return null ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// formats the string with invariant culture
/// </summary>
/// <param name="format">The format.</param>
/// <param name="args">The args.</param>
/// <returns></returns>
public static string InvariantFormat ( this string? format , params object? [ ] args ) = >
string . Format ( CultureInfo . InvariantCulture , format ? ? string . Empty , args ) ;
/// <summary>
/// Converts an integer to an invariant formatted string
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ToInvariantString ( this int str ) = > str . ToString ( CultureInfo . InvariantCulture ) ;
public static string ToInvariantString ( this long str ) = > str . ToString ( CultureInfo . InvariantCulture ) ;
/// <summary>
/// Compares 2 strings with invariant culture and case ignored
/// </summary>
/// <param name="compare">The compare.</param>
/// <param name="compareTo">The compare to.</param>
/// <returns></returns>
public static bool InvariantEquals ( this string? compare , string? compareTo ) = >
string . Equals ( compare , compareTo , StringComparison . InvariantCultureIgnoreCase ) ;
public static bool InvariantStartsWith ( this string compare , string compareTo ) = >
compare . StartsWith ( compareTo , StringComparison . InvariantCultureIgnoreCase ) ;
public static bool InvariantEndsWith ( this string compare , string compareTo ) = >
compare . EndsWith ( compareTo , StringComparison . InvariantCultureIgnoreCase ) ;
public static bool InvariantContains ( this string compare , string compareTo ) = >
compare . IndexOf ( compareTo , StringComparison . OrdinalIgnoreCase ) > = 0 ;
public static bool InvariantContains ( this IEnumerable < string > compare , string compareTo ) = >
compare . Contains ( compareTo , StringComparer . InvariantCultureIgnoreCase ) ;
public static int InvariantIndexOf ( this string s , string value ) = >
s . IndexOf ( value , StringComparison . OrdinalIgnoreCase ) ;
public static int InvariantLastIndexOf ( this string s , string value ) = >
s . LastIndexOf ( value , StringComparison . OrdinalIgnoreCase ) ;
/// <summary>
/// Tries to parse a string into the supplied type by finding and using the Type's "Parse" method
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="val"></param>
/// <returns></returns>
public static T ? ParseInto < T > ( this string val ) = > ( T ? ) val . ParseInto ( typeof ( T ) ) ;
/// <summary>
/// Tries to parse a string into the supplied type by finding and using the Type's "Parse" method
/// </summary>
/// <param name="val"></param>
/// <param name="type"></param>
/// <returns></returns>
public static object? ParseInto ( this string val , Type type )
{
if ( string . IsNullOrEmpty ( val ) = = false )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
TypeConverter tc = TypeDescriptor . GetConverter ( type ) ;
return tc . ConvertFrom ( val ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return val ;
}
/// <summary>
/// Generates a hash of a string based on the FIPS compliance setting.
/// </summary>
/// <param name="str">Refers to itself</param>
/// <returns>The hashed string</returns>
public static string GenerateHash ( this string str ) = > str . ToSHA1 ( ) ;
/// <summary>
/// Generate a hash of a string based on the specified hash algorithm.
/// </summary>
/// <typeparam name="T">The hash algorithm implementation to use.</typeparam>
/// <param name="str">The <see cref="string" /> to hash.</param>
/// <returns>
/// The hashed string.
/// </returns>
public static string GenerateHash < T > ( this string str )
where T : HashAlgorithm = > str . GenerateHash ( typeof ( T ) . FullName ) ;
/// <summary>
/// Converts the string to SHA1
/// </summary>
/// <param name="stringToConvert">refers to itself</param>
/// <returns>The SHA1 hashed string</returns>
public static string ToSHA1 ( this string stringToConvert ) = > stringToConvert . GenerateHash ( "SHA1" ) ;
/// <summary>
/// Decodes a string that was encoded with UrlTokenEncode
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static byte [ ] UrlTokenDecode ( this string input )
{
if ( input = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( input ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( input . Length = = 0 )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return Array . Empty < byte > ( ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
// calc array size - must be groups of 4
var arrayLength = input . Length ;
var remain = arrayLength % 4 ;
if ( remain ! = 0 )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
arrayLength + = 4 - remain ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
var inArray = new char [ arrayLength ] ;
for ( var i = 0 ; i < input . Length ; i + + )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
var ch = input [ i ] ;
switch ( ch )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
case '-' : // restore '-' as '+'
inArray [ i ] = '+' ;
break ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
case '_' : // restore '_' as '/'
inArray [ i ] = '/' ;
break ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
default : // keep char unchanged
inArray [ i ] = ch ;
break ;
2019-05-20 17:57:28 +02:00
}
}
2022-06-07 15:28:38 +02:00
// pad with '='
for ( var j = input . Length ; j < inArray . Length ; j + + )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
inArray [ j ] = '=' ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
return Convert . FromBase64CharArray ( inArray , 0 , inArray . Length ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Generate a hash of a string based on the hashType passed in
/// </summary>
/// <param name="str">Refers to itself</param>
/// <param name="hashType">
/// String with the hash type. See remarks section of the CryptoConfig Class in MSDN docs for a
/// list of possible values.
/// </param>
/// <returns>The hashed string</returns>
private static string GenerateHash ( this string str , string? hashType )
{
HashAlgorithm ? hasher = null ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// create an instance of the correct hashing provider based on the type passed in
if ( hashType is not null )
{
hasher = HashAlgorithm . Create ( hashType ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( hasher = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new InvalidOperationException ( "No hashing type found by name " + hashType ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
using ( hasher )
{
// convert our string into byte array
var byteArray = Encoding . UTF8 . GetBytes ( str ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// get the hashed values created by our selected provider
var hashedByteArray = hasher . ComputeHash ( byteArray ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// create a StringBuilder object
var stringBuilder = new StringBuilder ( ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// loop to each byte
foreach ( var b in hashedByteArray )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
// append it to our StringBuilder
stringBuilder . Append ( b . ToString ( "x2" ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
// return the hashed value
return stringBuilder . ToString ( ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Encodes a string so that it is 'safe' for URLs, files, etc..
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string UrlTokenEncode ( this byte [ ] input )
{
if ( input = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( input ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( input . Length = = 0 )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return string . Empty ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// base-64 digits are A-Z, a-z, 0-9, + and /
// the = char is used for trailing padding
var str = Convert . ToBase64String ( input ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
var pos = str . IndexOf ( '=' ) ;
if ( pos < 0 )
{
pos = str . Length ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// replace chars that would cause problems in URLs
var chArray = new char [ pos ] ;
for ( var i = 0 ; i < pos ; i + + )
{
var ch = str [ i ] ;
switch ( ch )
{
case '+' : // replace '+' with '-'
chArray [ i ] = '-' ;
break ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
case '/' : // replace '/' with '_'
chArray [ i ] = '_' ;
break ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
default : // keep char unchanged
chArray [ i ] = ch ;
break ;
}
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return new string ( chArray ) ;
}
/// <summary>
/// Ensures that the folder path ends with a DirectorySeparatorChar
/// </summary>
/// <param name="currentFolder"></param>
/// <returns></returns>
public static string NormaliseDirectoryPath ( this string currentFolder )
{
currentFolder = currentFolder
. IfNull ( x = > string . Empty )
. TrimEnd ( Path . DirectorySeparatorChar ) + Path . DirectorySeparatorChar ;
return currentFolder ;
}
/// <summary>
/// Truncates the specified text string.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="maxLength">Length of the max.</param>
/// <param name="suffix">The suffix.</param>
/// <returns></returns>
public static string Truncate ( this string text , int maxLength , string suffix = "..." )
{
// replaces the truncated string to a ...
var truncatedString = text ;
if ( maxLength < = 0 )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return truncatedString ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
var strLength = maxLength - suffix . Length ;
if ( strLength < = 0 )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return truncatedString ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( text = = null | | text . Length < = maxLength )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return truncatedString ;
2019-05-20 17:57:28 +02:00
}
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
truncatedString = text [ . . strLength ] ;
2022-06-07 15:28:38 +02:00
truncatedString = truncatedString . TrimEnd ( ) ;
truncatedString + = suffix ;
return truncatedString ;
}
/// <summary>
/// Strips carrage returns and line feeds from the specified text.
/// </summary>
/// <param name="input">The input.</param>
/// <returns></returns>
public static string StripNewLines ( this string input ) = > input . Replace ( "\r" , string . Empty ) . Replace ( "\n" , string . Empty ) ;
/// <summary>
/// Converts to single line by replacing line breaks with spaces.
/// </summary>
public static string ToSingleLine ( this string text )
{
if ( string . IsNullOrEmpty ( text ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return text ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
text = text . Replace ( "\r\n" , " " ) ; // remove CRLF
text = text . Replace ( "\r" , " " ) ; // remove CR
text = text . Replace ( "\n" , " " ) ; // remove LF
return text ;
}
public static string OrIfNullOrWhiteSpace ( this string input , string alternative ) = >
! string . IsNullOrWhiteSpace ( input )
? input
: alternative ;
/// <summary>
/// Returns a copy of the string with the first character converted to uppercase.
/// </summary>
/// <param name="input">The string.</param>
/// <returns>The converted string.</returns>
public static string ToFirstUpper ( this string input ) = >
string . IsNullOrWhiteSpace ( input )
? input
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
: input [ . . 1 ] . ToUpper ( ) + input [ 1. . ] ;
2022-06-07 15:28:38 +02:00
/// <summary>
/// Returns a copy of the string with the first character converted to lowercase.
/// </summary>
/// <param name="input">The string.</param>
/// <returns>The converted string.</returns>
public static string ToFirstLower ( this string input ) = >
string . IsNullOrWhiteSpace ( input )
? input
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
: input [ . . 1 ] . ToLower ( ) + input [ 1. . ] ;
2022-06-07 15:28:38 +02:00
/// <summary>
/// Returns a copy of the string with the first character converted to uppercase using the casing rules of the
/// specified culture.
/// </summary>
/// <param name="input">The string.</param>
/// <param name="culture">The culture.</param>
/// <returns>The converted string.</returns>
public static string ToFirstUpper ( this string input , CultureInfo culture ) = >
string . IsNullOrWhiteSpace ( input )
? input
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
: input [ . . 1 ] . ToUpper ( culture ) + input [ 1. . ] ;
2022-06-07 15:28:38 +02:00
/// <summary>
/// Returns a copy of the string with the first character converted to lowercase using the casing rules of the
/// specified culture.
/// </summary>
/// <param name="input">The string.</param>
/// <param name="culture">The culture.</param>
/// <returns>The converted string.</returns>
public static string ToFirstLower ( this string input , CultureInfo culture ) = >
string . IsNullOrWhiteSpace ( input )
? input
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
: input [ . . 1 ] . ToLower ( culture ) + input [ 1. . ] ;
2022-06-07 15:28:38 +02:00
/// <summary>
/// Returns a copy of the string with the first character converted to uppercase using the casing rules of the
/// invariant culture.
/// </summary>
/// <param name="input">The string.</param>
/// <returns>The converted string.</returns>
public static string ToFirstUpperInvariant ( this string input ) = >
string . IsNullOrWhiteSpace ( input )
? input
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
: input [ . . 1 ] . ToUpperInvariant ( ) + input [ 1. . ] ;
2022-06-07 15:28:38 +02:00
/// <summary>
/// Returns a copy of the string with the first character converted to lowercase using the casing rules of the
/// invariant culture.
/// </summary>
/// <param name="input">The string.</param>
/// <returns>The converted string.</returns>
public static string ToFirstLowerInvariant ( this string input ) = >
string . IsNullOrWhiteSpace ( input )
? input
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
: input [ . . 1 ] . ToLowerInvariant ( ) + input [ 1. . ] ;
2022-06-07 15:28:38 +02:00
/// <summary>
/// Returns a new string in which all occurrences of specified strings are replaced by other specified strings.
/// </summary>
/// <param name="text">The string to filter.</param>
/// <param name="replacements">The replacements definition.</param>
/// <returns>The filtered string.</returns>
public static string ReplaceMany ( this string text , IDictionary < string , string > replacements )
{
if ( text = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( text ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( replacements = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( replacements ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
foreach ( KeyValuePair < string , string > item in replacements )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
text = text . Replace ( item . Key , item . Value ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return text ;
}
/// <summary>
/// Returns a new string in which all occurrences of specified characters are replaced by a specified character.
/// </summary>
/// <param name="text">The string to filter.</param>
/// <param name="chars">The characters to replace.</param>
/// <param name="replacement">The replacement character.</param>
/// <returns>The filtered string.</returns>
public static string ReplaceMany ( this string text , char [ ] chars , char replacement )
{
if ( text = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( text ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( chars = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( chars ) ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
for ( var i = 0 ; i < chars . Length ; i + + )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
text = text . Replace ( chars [ i ] , replacement ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
return text ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Returns a new string in which only the first occurrence of a specified string is replaced by a specified
/// replacement string.
/// </summary>
/// <param name="text">The string to filter.</param>
/// <param name="search">The string to replace.</param>
/// <param name="replace">The replacement string.</param>
/// <returns>The filtered string.</returns>
public static string ReplaceFirst ( this string text , string search , string replace )
{
if ( text = = null )
{
throw new ArgumentNullException ( nameof ( text ) ) ;
}
2019-05-20 17:57:28 +02:00
2023-03-23 21:11:59 +01:00
ReadOnlySpan < char > spanText = text . AsSpan ( ) ;
var pos = spanText . IndexOf ( search , StringComparison . InvariantCulture ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
if ( pos < 0 )
{
2019-05-20 17:57:28 +02:00
return text ;
}
2023-03-23 21:11:59 +01:00
return string . Concat ( spanText [ . . pos ] , replace . AsSpan ( ) , spanText [ ( pos + search . Length ) . . ] ) ;
2022-06-07 15:28:38 +02:00
}
2020-03-31 16:28:13 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// An extension method that returns a new string in which all occurrences of a
/// specified string in the current instance are replaced with another specified string.
/// StringComparison specifies the type of search to use for the specified string.
/// </summary>
/// <param name="source">Current instance of the string</param>
/// <param name="oldString">Specified string to replace</param>
/// <param name="newString">Specified string to inject</param>
/// <param name="stringComparison">String Comparison object to specify search type</param>
/// <returns>Updated string</returns>
public static string Replace ( this string source , string oldString , string newString , StringComparison stringComparison )
{
// This initialization ensures the first check starts at index zero of the source. On successive checks for
// a match, the source is skipped to immediately after the last replaced occurrence for efficiency
// and to avoid infinite loops when oldString and newString compare equal.
var index = - 1 * newString . Length ;
2020-03-17 10:21:43 +01:00
2022-06-07 15:28:38 +02:00
// Determine if there are any matches left in source, starting from just after the result of replacing the last match.
while ( ( index = source . IndexOf ( oldString , index + newString . Length , stringComparison ) ) > = 0 )
{
// Remove the old text.
source = source . Remove ( index , oldString . Length ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// Add the replacement text.
source = source . Insert ( index , newString ) ;
2020-03-17 10:21:43 +01:00
}
2019-10-30 15:28:15 +01:00
2022-06-07 15:28:38 +02:00
return source ;
}
2019-10-30 15:28:15 +01:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Converts a literal string into a C# expression.
/// </summary>
/// <param name="s">Current instance of the string.</param>
/// <returns>The string in a C# format.</returns>
public static string ToCSharpString ( this string s )
{
if ( s = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
return "<null>" ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
// http://stackoverflow.com/questions/323640/can-i-convert-a-c-sharp-string-value-to-an-escaped-string-literal
var sb = new StringBuilder ( s . Length + 2 ) ;
for ( var rp = 0 ; rp < s . Length ; rp + + )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
var c = s [ rp ] ;
if ( c < ToCSharpEscapeChars . Length & & ToCSharpEscapeChars [ c ] ! = '\0' )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
sb . Append ( '\\' ) . Append ( ToCSharpEscapeChars [ c ] ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
else if ( c < = '~' & & c > = ' ' )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
sb . Append ( c ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
else
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
sb . Append ( @"\x" )
. Append ( ToCSharpHexDigitLower [ ( c > > 12 ) & 0x0F ] )
. Append ( ToCSharpHexDigitLower [ ( c > > 8 ) & 0x0F ] )
. Append ( ToCSharpHexDigitLower [ ( c > > 4 ) & 0x0F ] )
. Append ( ToCSharpHexDigitLower [ c & 0x0F ] ) ;
2019-05-20 17:57:28 +02:00
}
}
2022-06-07 15:28:38 +02:00
return sb . ToString ( ) ;
// requires full trust
/ *
using ( var writer = new StringWriter ( ) )
using ( var provider = CodeDomProvider . CreateProvider ( "CSharp" ) )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
provider . GenerateCodeFromExpression ( new CodePrimitiveExpression ( s ) , writer , null ) ;
return writer . ToString ( ) . Replace ( string . Format ( "\" +{0}\t\"" , Environment . NewLine ) , "" ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
* /
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
public static string EscapeRegexSpecialCharacters ( this string text )
{
var regexSpecialCharacters = new Dictionary < string , string >
{
{ "." , @"\." } ,
{ "(" , @"\(" } ,
{ ")" , @"\)" } ,
{ "]" , @"\]" } ,
{ "[" , @"\[" } ,
{ "{" , @"\{" } ,
{ "}" , @"\}" } ,
{ "?" , @"\?" } ,
{ "!" , @"\!" } ,
{ "$" , @"\$" } ,
{ "^" , @"\^" } ,
{ "+" , @"\+" } ,
{ "*" , @"\*" } ,
{ "|" , @"\|" } ,
{ "<" , @"\<" } ,
{ ">" , @"\>" } ,
} ;
return ReplaceMany ( text , regexSpecialCharacters ) ;
}
/// <summary>
/// Checks whether a string "haystack" contains within it any of the strings in the "needles" collection and returns
/// true if it does or false if it doesn't
/// </summary>
/// <param name="haystack">The string to check</param>
/// <param name="needles">The collection of strings to check are contained within the first string</param>
/// <param name="comparison">
/// The type of comparison to perform - defaults to <see cref="StringComparison.CurrentCulture" />
/// </param>
/// <returns>True if any of the needles are contained with haystack; otherwise returns false</returns>
/// Added fix to ensure the comparison is used - see http://issues.umbraco.org/issue/U4-11313
public static bool ContainsAny ( this string haystack , IEnumerable < string > needles , StringComparison comparison = StringComparison . CurrentCulture )
{
if ( haystack = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( "haystack" ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
if ( string . IsNullOrEmpty ( haystack ) | | needles = = null | | ! needles . Any ( ) )
{
return false ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
return needles . Any ( value = > haystack . IndexOf ( value , comparison ) > = 0 ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
public static bool CsvContains ( this string csv , string value )
{
if ( string . IsNullOrEmpty ( csv ) )
{
return false ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
var idCheckList = csv . Split ( Constants . CharArrays . Comma , StringSplitOptions . RemoveEmptyEntries ) ;
return idCheckList . Contains ( value ) ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Converts a file name to a friendly name for a content item
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ToFriendlyName ( this string fileName )
{
// strip the file extension
fileName = fileName . StripFileExtension ( ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// underscores and dashes to spaces
fileName = fileName . ReplaceMany ( Constants . CharArrays . UnderscoreDash , ' ' ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// any other conversions ?
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// Pascalcase (to be done last)
fileName = CultureInfo . InvariantCulture . TextInfo . ToTitleCase ( fileName ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
// Replace multiple consecutive spaces with a single space
fileName = string . Join ( " " , fileName . Split ( Constants . CharArrays . Space , StringSplitOptions . RemoveEmptyEntries ) ) ;
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
return fileName ;
}
2019-05-20 17:57:28 +02:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// An extension method that returns a new string in which all occurrences of an
/// unicode characters that are invalid in XML files are replaced with an empty string.
/// </summary>
/// <param name="text">Current instance of the string</param>
/// <returns>Updated string</returns>
/// <summary>
/// removes any unusual unicode characters that can't be encoded into XML
/// </summary>
public static string ToValidXmlString ( this string text ) = >
string . IsNullOrEmpty ( text ) ? text : InvalidXmlChars . Value . Replace ( text , string . Empty ) ;
/// <summary>
/// Converts a string to a Guid - WARNING, depending on the string, this may not be unique
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static Guid ToGuid ( this string text ) = >
CreateGuidFromHash (
UrlNamespace ,
text ,
CryptoConfig . AllowOnlyFipsAlgorithms ? 5 // SHA1
: 3 ) ; // MD5
/// <summary>
/// Turns an null-or-whitespace string into a null string.
/// </summary>
2022-11-08 09:22:23 +01:00
public static string? NullOrWhiteSpaceAsNull ( this string? text )
2022-06-07 15:28:38 +02:00
= > string . IsNullOrWhiteSpace ( text ) ? null : text ;
/// <summary>
/// Creates a name-based UUID using the algorithm from RFC 4122 §4.3.
/// See
/// <a href="https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs#L34">GuidUtility.cs</a>
/// for original implementation.
/// </summary>
/// <param name="namespaceId">The ID of the namespace.</param>
/// <param name="name">The name (within that namespace).</param>
/// <param name="version">
/// The version number of the UUID to create; this value must be either
/// 3 (for MD5 hashing) or 5 (for SHA-1 hashing).
/// </param>
/// <returns>A UUID derived from the namespace and name.</returns>
/// <remarks>
/// See
/// <a href="http://code.logos.com/blog/2011/04/generating_a_deterministic_guid.html">Generating a deterministic GUID</a>
/// .
/// </remarks>
internal static Guid CreateGuidFromHash ( Guid namespaceId , string name , int version )
{
if ( name = = null )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( "name" ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
if ( version ! = 3 & & version ! = 5 )
2019-05-20 17:57:28 +02:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentOutOfRangeException ( "version" , "version must be either 3 or 5." ) ;
2019-05-20 17:57:28 +02:00
}
2022-06-07 15:28:38 +02:00
// convert the name to a sequence of octets (as defined by the standard or conventions of its namespace) (step 3)
// ASSUME: UTF-8 encoding is always appropriate
var nameBytes = Encoding . UTF8 . GetBytes ( name ) ;
2019-12-05 10:41:58 +01:00
2022-06-07 15:28:38 +02:00
// convert the namespace UUID to network order (step 3)
var namespaceBytes = namespaceId . ToByteArray ( ) ;
SwapByteOrder ( namespaceBytes ) ;
2019-12-05 10:41:58 +01:00
2022-06-07 15:28:38 +02:00
// comput the hash of the name space ID concatenated with the name (step 4)
byte [ ] hash ;
using ( HashAlgorithm algorithm = version = = 3 ? MD5 . Create ( ) : SHA1 . Create ( ) )
2019-12-05 10:41:58 +01:00
{
2022-06-07 15:28:38 +02:00
algorithm . TransformBlock ( namespaceBytes , 0 , namespaceBytes . Length , null , 0 ) ;
algorithm . TransformFinalBlock ( nameBytes , 0 , nameBytes . Length ) ;
hash = algorithm . Hash ! ;
2019-12-05 10:41:58 +01:00
}
2022-06-07 15:28:38 +02:00
// most bytes from the hash are copied straight to the bytes of the new GUID (steps 5-7, 9, 11-12)
var newGuid = new byte [ 16 ] ;
Array . Copy ( hash , 0 , newGuid , 0 , 16 ) ;
2019-12-20 17:36:44 +01:00
2022-06-07 15:28:38 +02:00
// set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the appropriate 4-bit version number from Section 4.1.3 (step 8)
newGuid [ 6 ] = ( byte ) ( ( newGuid [ 6 ] & 0x0F ) | ( version < < 4 ) ) ;
2019-12-20 17:36:44 +01:00
2022-06-07 15:28:38 +02:00
// set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively (step 10)
newGuid [ 8 ] = ( byte ) ( ( newGuid [ 8 ] & 0x3F ) | 0x80 ) ;
2019-12-20 17:36:44 +01:00
2022-06-07 15:28:38 +02:00
// convert the resulting UUID to local byte order (step 13)
SwapByteOrder ( newGuid ) ;
return new Guid ( newGuid ) ;
}
2019-12-20 17:36:44 +01:00
2022-06-07 15:28:38 +02:00
// Converts a GUID (expressed as a byte array) to/from network order (MSB-first).
internal static void SwapByteOrder ( byte [ ] guid )
{
SwapBytes ( guid , 0 , 3 ) ;
SwapBytes ( guid , 1 , 2 ) ;
SwapBytes ( guid , 4 , 5 ) ;
SwapBytes ( guid , 6 , 7 ) ;
}
2019-12-20 17:36:44 +01:00
2022-06-07 15:28:38 +02:00
private static void SwapBytes ( byte [ ] guid , int left , int right )
{
var temp = guid [ left ] ;
guid [ left ] = guid [ right ] ;
guid [ right ] = temp ;
}
2019-12-20 17:36:44 +01:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Checks if a given path is a full path including drive letter
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
2022-09-19 10:29:12 +02:00
public static bool IsFullPath ( this string path ) = > Path . IsPathFullyQualified ( path ) ;
2022-06-07 15:28:38 +02:00
// FORMAT STRINGS
/// <summary>
/// Cleans a string to produce a string that can safely be used in an alias.
/// </summary>
/// <param name="alias">The text to filter.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <returns>The safe alias.</returns>
public static string ToSafeAlias ( this string alias , IShortStringHelper ? shortStringHelper ) = >
shortStringHelper ? . CleanStringForSafeAlias ( alias ) ? ? string . Empty ;
/// <summary>
/// Cleans a string to produce a string that can safely be used in an alias.
/// </summary>
/// <param name="alias">The text to filter.</param>
/// <param name="camel">A value indicating that we want to camel-case the alias.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <returns>The safe alias.</returns>
public static string ToSafeAlias ( this string alias , IShortStringHelper shortStringHelper , bool camel )
{
var a = shortStringHelper . CleanStringForSafeAlias ( alias ) ;
if ( string . IsNullOrWhiteSpace ( a ) | | camel = = false )
2019-12-20 17:36:44 +01:00
{
2022-06-07 15:28:38 +02:00
return a ;
2019-12-20 17:36:44 +01:00
}
Resolved more warnings, and marked more warning types as errors (#16991)
* Fix warnings SA1111, SA1028, SA1500, IDE1270 in Umbraco.Web.Website, and updated rules.
* Remove warnings: IDE0270: Null check can be simplified
* More SqlServer project warnings resolved
* CS0105 namespace appeared already
* Suppress warning until implementation:
#pragma warning disable CS0162 // Unreachable code detected
#pragma warning disable CS0618 // Type or member is obsolete
CS0162 remove unreachable code
SA1028 remove trailing whitespace
SA1106 no empty statements
CS1570 malformed XML
CS1572 corrected xml parameter
CS1573 param tag added
IDE0007 var not explicit
IDE0008 explicit not var
IDE0057 simplify substring
IDE0074 compound assignment
CA1825 array.empty
Down to 3479 warnings
* - SA1116, SA117 params on same line
- IDE0057 substring simplified
Specific warnings for Umbraco.Tests.Benchmarks
* Fixed IDE0074 compound assignment and added specific warnings for Umbraco.Tests.Common
* Specific warnings for Umbraco.Tests.Integration and Umbraco.Tests.Common
Fixed:
- SA1111, SA1116, SA117 params and line formatting (not all as there are many)
- SA1122 string.Empty
- IDE0057 simplify substring
- IDE0044,IDE0044 make field readonly
- IDE1006 naming rule violation (add _)
- SA1111 closing parenthesis on line of last parameter
- SA1649 filename match type name
- SA1312,SA1306 lowercase variable and field names
* Fixed various warnings where they are more straight-forward, including:
- SA1649 file name match type name
- SA111 parenthesis on line of last parameter
- IDE0028 simplify collection initializer
- SA1306 lower-case letter field
- IDE044 readonly field
- SA1122 string.Empty
- SA1116 params same line
- IDE1006 upper casing
- IDE0041 simplify null check
Updated the following projects to only list their remaining specific warning codes:
- Umbraco.Tests.UnitTests
Typo in `Umbraco.Web.Website` project
* Reverted test change
* Now 1556 warnings.
Fixed various warnings where they are more straight-forward, including:
- SA1111/SA1116/SA1119 parenthesis
- SA1117 params
- SA1312 lowercase variable
- SA1121 built-in type
- SA1500/SA1513/SA1503 formatting braces
- SA1400 declare access modifier
- SA1122 string.Empty
- SA1310 no underscore
- IDE0049 name simplified
- IDE0057 simplify substring
- IDE0074 compound assignment
- IDE0032 use auto-property
- IDE0037 simplify member name
- IDE0008 explicit type not var
- IDE0016/IDE0270/IDE0041 simplify null checks
- IDE0048/SA1407 clarity in arithmetic
- IDE1006 correct param names
- IDE0042 deconstruct variable
- IDE0044 readonly
- IDE0018 inline variable declarations
- IDE0074/IDE0054 compound assignment
- IDE1006 naming
- CS1573 param XML
- CS0168 unused variable
Comment formatting in project files for consistency.
Updated all projects to only list remaining specific warning codes as warnings instead of errors (errors is now default).
* Type not var, and more warning exceptions
* Tweaked merge issue, readded comment about rollback
* Readded comment re rollback.
* Readded comments
* Comment tweak
* Comment tweak
2024-09-24 12:56:28 +01:00
return char . ToLowerInvariant ( a [ 0 ] ) + a [ 1. . ] ;
2022-06-07 15:28:38 +02:00
}
2019-12-20 17:36:44 +01:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Cleans a string, in the context of a specified culture, to produce a string that can safely be used in an alias.
/// </summary>
/// <param name="alias">The text to filter.</param>
/// <param name="culture">The culture.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <returns>The safe alias.</returns>
public static string ToSafeAlias ( this string alias , IShortStringHelper shortStringHelper , string culture ) = >
shortStringHelper . CleanStringForSafeAlias ( alias , culture ) ;
// the new methods to get a url segment
/// <summary>
/// Cleans a string to produce a string that can safely be used in an url segment.
/// </summary>
/// <param name="text">The text to filter.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <returns>The safe url segment.</returns>
public static string ToUrlSegment ( this string text , IShortStringHelper shortStringHelper )
{
if ( text = = null )
2019-12-09 14:12:06 +01:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( text ) ) ;
2019-12-09 14:12:06 +01:00
}
2022-06-07 15:28:38 +02:00
if ( string . IsNullOrWhiteSpace ( text ) )
2019-12-09 14:12:06 +01:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentException (
"Value can't be empty or consist only of white-space characters." ,
nameof ( text ) ) ;
2019-12-09 14:12:06 +01:00
}
2022-06-07 15:28:38 +02:00
return shortStringHelper . CleanStringForUrlSegment ( text ) ;
}
2019-12-09 14:12:06 +01:00
2022-06-07 15:28:38 +02:00
/// <summary>
/// Cleans a string, in the context of a specified culture, to produce a string that can safely be used in an url
/// segment.
/// </summary>
/// <param name="text">The text to filter.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <param name="culture">The culture.</param>
/// <returns>The safe url segment.</returns>
public static string ToUrlSegment ( this string text , IShortStringHelper shortStringHelper , string? culture )
{
if ( text = = null )
2019-12-09 14:12:06 +01:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentNullException ( nameof ( text ) ) ;
2019-12-09 14:12:06 +01:00
}
2019-12-18 18:55:00 +01:00
2022-06-07 15:28:38 +02:00
if ( string . IsNullOrWhiteSpace ( text ) )
2019-12-18 18:55:00 +01:00
{
2022-06-07 15:28:38 +02:00
throw new ArgumentException (
"Value can't be empty or consist only of white-space characters." ,
nameof ( text ) ) ;
2019-12-18 18:55:00 +01:00
}
2022-06-07 15:28:38 +02:00
return shortStringHelper . CleanStringForUrlSegment ( text , culture ) ;
}
/// <summary>
/// Cleans a string.
/// </summary>
/// <param name="text">The text to clean.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <param name="stringType">
/// A flag indicating the target casing and encoding of the string. By default,
/// strings are cleaned up to camelCase and Ascii.
/// </param>
/// <returns>The clean string.</returns>
/// <remarks>The string is cleaned in the context of the ICurrent.ShortStringHelper default culture.</remarks>
public static string ToCleanString ( this string text , IShortStringHelper shortStringHelper , CleanStringType stringType ) = > shortStringHelper . CleanString ( text , stringType ) ;
/// <summary>
/// Cleans a string, using a specified separator.
/// </summary>
/// <param name="text">The text to clean.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <param name="stringType">
/// A flag indicating the target casing and encoding of the string. By default,
/// strings are cleaned up to camelCase and Ascii.
/// </param>
/// <param name="separator">The separator.</param>
/// <returns>The clean string.</returns>
/// <remarks>The string is cleaned in the context of the ICurrent.ShortStringHelper default culture.</remarks>
public static string ToCleanString ( this string text , IShortStringHelper shortStringHelper , CleanStringType stringType , char separator ) = > shortStringHelper . CleanString ( text , stringType , separator ) ;
/// <summary>
/// Cleans a string in the context of a specified culture.
/// </summary>
/// <param name="text">The text to clean.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <param name="stringType">
/// A flag indicating the target casing and encoding of the string. By default,
/// strings are cleaned up to camelCase and Ascii.
/// </param>
/// <param name="culture">The culture.</param>
/// <returns>The clean string.</returns>
public static string ToCleanString ( this string text , IShortStringHelper shortStringHelper , CleanStringType stringType , string culture ) = > shortStringHelper . CleanString ( text , stringType , culture ) ;
/// <summary>
/// Cleans a string in the context of a specified culture, using a specified separator.
/// </summary>
/// <param name="text">The text to clean.</param>
/// <param name="shortStringHelper">The short string helper.</param>
/// <param name="stringType">
/// A flag indicating the target casing and encoding of the string. By default,
/// strings are cleaned up to camelCase and Ascii.
/// </param>
/// <param name="separator">The separator.</param>
/// <param name="culture">The culture.</param>
/// <returns>The clean string.</returns>
public static string ToCleanString ( this string text , IShortStringHelper shortStringHelper , CleanStringType stringType , char separator , string culture ) = >
shortStringHelper . CleanString ( text , stringType , separator , culture ) ;
// note: LegacyCurrent.ShortStringHelper will produce 100% backward-compatible output for SplitPascalCasing.
// other helpers may not. DefaultCurrent.ShortStringHelper produces better, but non-compatible, results.
/// <summary>
/// Splits a Pascal cased string into a phrase separated by spaces.
/// </summary>
/// <param name="phrase">The text to split.</param>
/// <param name="shortStringHelper"></param>
/// <returns>The split text.</returns>
public static string SplitPascalCasing ( this string phrase , IShortStringHelper shortStringHelper ) = >
shortStringHelper . SplitPascalCasing ( phrase , ' ' ) ;
/// <summary>
/// Cleans a string, in the context of the invariant culture, to produce a string that can safely be used as a
/// filename,
/// both internally (on disk) and externally (as a url).
/// </summary>
/// <param name="text">The text to filter.</param>
/// <param name="shortStringHelper"></param>
/// <returns>The safe filename.</returns>
public static string ToSafeFileName ( this string text , IShortStringHelper shortStringHelper ) = >
shortStringHelper . CleanStringForSafeFileName ( text ) ;
// NOTE: Not sure what this actually does but is used a few places, need to figure it out and then move to StringExtensions and obsolete.
// it basically is yet another version of SplitPascalCasing
// plugging string extensions here to be 99% compatible
// the only diff. is with numbers, Number6Is was "Number6 Is", and the new string helper does it too,
// but the legacy one does "Number6Is"... assuming it is not a big deal.
internal static string SpaceCamelCasing ( this string phrase , IShortStringHelper shortStringHelper ) = >
phrase . Length < 2 ? phrase : phrase . SplitPascalCasing ( shortStringHelper ) . ToFirstUpperInvariant ( ) ;
/// <summary>
/// Cleans a string, in the context of the invariant culture, to produce a string that can safely be used as a
/// filename,
/// both internally (on disk) and externally (as a url).
/// </summary>
/// <param name="text">The text to filter.</param>
/// <param name="shortStringHelper"></param>
/// <param name="culture">The culture.</param>
/// <returns>The safe filename.</returns>
public static string ToSafeFileName ( this string text , IShortStringHelper shortStringHelper , string culture ) = >
shortStringHelper . CleanStringForSafeFileName ( text , culture ) ;
/// <summary>
/// Splits a string with an escape character that allows for the split character to exist in a string
/// </summary>
/// <param name="value">The string to split</param>
/// <param name="splitChar">The character to split on</param>
/// <param name="escapeChar">The character which can be used to escape the character to split on</param>
/// <returns>The string split into substrings delimited by the split character</returns>
public static IEnumerable < string > EscapedSplit ( this string value , char splitChar , char escapeChar = DefaultEscapedStringEscapeChar )
{
if ( value = = null )
2019-12-18 18:55:00 +01:00
{
2022-06-07 15:28:38 +02:00
yield break ;
2019-12-18 18:55:00 +01:00
}
2022-06-07 15:28:38 +02:00
var sb = new StringBuilder ( value . Length ) ;
var escaped = false ;
2021-03-18 15:04:03 -07:00
2022-06-07 15:28:38 +02:00
foreach ( var chr in value . ToCharArray ( ) )
{
if ( escaped )
2021-03-18 15:04:03 -07:00
{
2022-06-07 15:28:38 +02:00
escaped = false ;
sb . Append ( chr ) ;
}
else if ( chr = = splitChar )
{
yield return sb . ToString ( ) ;
sb . Clear ( ) ;
}
else if ( chr = = escapeChar )
{
escaped = true ;
}
else
{
sb . Append ( chr ) ;
2021-03-18 15:04:03 -07:00
}
}
2022-06-07 15:28:38 +02:00
yield return sb . ToString ( ) ;
2019-05-20 17:57:28 +02:00
}
2023-11-14 11:16:12 +01:00
2024-11-25 13:55:40 +01:00
/// <summary>
/// Checks whether a string is a valid email address.
/// </summary>
/// <param name="email">The string check</param>
/// <returns>Returns a bool indicating whether the string is an email address.</returns>
public static bool IsEmail ( this string? email ) = >
string . IsNullOrWhiteSpace ( email ) is false & & new EmailAddressAttribute ( ) . IsValid ( email ) ;
2023-11-14 11:16:12 +01:00
// having benchmarked various solutions (incl. for/foreach, split and LINQ based ones),
// this is by far the fastest way to find string needles in a string haystack
public static int CountOccurrences ( this string haystack , string needle )
= > haystack . Length - haystack . Replace ( needle , string . Empty ) . Length ;
2019-05-20 17:57:28 +02:00
}