StringExtensions
Useful methods for string objects.
using AngleSharp.Attributes;
using AngleSharp.Css;
using AngleSharp.Css.Values;
using AngleSharp.Dom;
using AngleSharp.Network;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
namespace AngleSharp.Extensions
{
internal static class StringExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Has(this string value, char chr, int index = 0)
{
if (value != null && value.Length > index)
return value[index] == chr;
return false;
}
public static string GetCompatiblity(this QuirksMode mode)
{
return typeof(QuirksMode).GetTypeInfo().GetDeclaredField(mode.ToString()).GetCustomAttribute<DomDescriptionAttribute>()?.Description ?? "CSS1Compat";
}
public static Sandboxes ParseSecuritySettings(this string value, bool allowFullscreen = false)
{
string[] list = value.SplitSpaces();
Sandboxes sandboxes = Sandboxes.Navigation | Sandboxes.Plugins | Sandboxes.DocumentDomain;
if (!list.Contains("allow-popups", StringComparison.OrdinalIgnoreCase))
sandboxes |= Sandboxes.AuxiliaryNavigation;
if (!list.Contains("allow-top-navigation", StringComparison.OrdinalIgnoreCase))
sandboxes |= Sandboxes.TopLevelNavigation;
if (!list.Contains("allow-same-origin", StringComparison.OrdinalIgnoreCase))
sandboxes |= Sandboxes.Origin;
if (!list.Contains("allow-forms", StringComparison.OrdinalIgnoreCase))
sandboxes |= Sandboxes.Forms;
if (!list.Contains("allow-pointer-lock", StringComparison.OrdinalIgnoreCase))
sandboxes |= Sandboxes.PointerLock;
if (!list.Contains("allow-scripts", StringComparison.OrdinalIgnoreCase))
sandboxes |= Sandboxes.Scripts;
if (!list.Contains("allow-scripts", StringComparison.OrdinalIgnoreCase))
sandboxes |= Sandboxes.AutomaticFeatures;
if (!allowFullscreen)
sandboxes |= Sandboxes.Fullscreen;
return sandboxes;
}
public static T ToEnum<T>(this string value, T defaultValue) where T : struct, IComparable
{
T result = default(T);
if (!string.IsNullOrEmpty(value) && Enum.TryParse(value, true, out result))
return result;
return defaultValue;
}
public static double ToDouble(this string value, double defaultValue = 0)
{
double result = 0;
if (!string.IsNullOrEmpty(value) && double.TryParse(value, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out result))
return result;
return defaultValue;
}
public static int ToInteger(this string value, int defaultValue = 0)
{
int result = 0;
if (!string.IsNullOrEmpty(value) && int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
return result;
return defaultValue;
}
public static uint ToInteger(this string value, uint defaultValue = 0)
{
uint result = 0;
if (!string.IsNullOrEmpty(value) && uint.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
return result;
return defaultValue;
}
public static bool ToBoolean(this string value, bool defaultValue = false)
{
bool result = false;
if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out result))
return result;
return defaultValue;
}
public static string ReplaceFirst(this string text, string search, string replace)
{
int num = text.IndexOf(search);
if (num < 0)
return text;
return text.Substring(0, num) + replace + text.Substring(num + search.Length);
}
public static string CollapseAndStrip(this string str)
{
char[] array = new char[str.Length];
bool flag = true;
int num = 0;
for (int i = 0; i < str.Length; i++) {
if (str[i].IsSpaceCharacter()) {
if (!flag) {
flag = true;
array[num++] = ' ';
}
} else {
flag = false;
array[num++] = str[i];
}
}
if (flag && num > 0)
num--;
return new string(array, 0, num);
}
public static string Collapse(this string str)
{
List<char> list = new List<char>();
bool flag = false;
for (int i = 0; i < str.Length; i++) {
if (str[i].IsSpaceCharacter()) {
if (!flag) {
list.Add(' ');
flag = true;
}
} else {
flag = false;
list.Add(str[i]);
}
}
return new string(list.ToArray());
}
public static bool Contains(this string[] list, string element, StringComparison comparison = StringComparison.Ordinal)
{
for (int i = 0; i < list.Length; i++) {
if (list[i].Equals(element, comparison))
return true;
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Is(this string current, string other)
{
return string.Equals(current, other, StringComparison.Ordinal);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Isi(this string current, string other)
{
return string.Equals(current, other, StringComparison.OrdinalIgnoreCase);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOneOf(this string element, string item1, string item2)
{
if (!element.Is(item1))
return element.Is(item2);
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOneOf(this string element, string item1, string item2, string item3)
{
if (!element.Is(item1) && !element.Is(item2))
return element.Is(item3);
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOneOf(this string element, string item1, string item2, string item3, string item4)
{
if (!element.Is(item1) && !element.Is(item2) && !element.Is(item3))
return element.Is(item4);
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOneOf(this string element, string item1, string item2, string item3, string item4, string item5)
{
if (!element.Is(item1) && !element.Is(item2) && !element.Is(item3) && !element.Is(item4))
return element.Is(item5);
return true;
}
public static string StripLineBreaks(this string str)
{
char[] array = str.ToCharArray();
int num = 0;
int num2 = array.Length;
int num3 = 0;
while (num3 < num2) {
array[num3] = array[num3 + num];
if (array[num3].IsLineBreak()) {
num++;
num2--;
} else
num3++;
}
return new string(array, 0, num2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string StripLeadingTrailingSpaces(this string str)
{
return str.ToCharArray().StripLeadingTrailingSpaces();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string StripLeadingTrailingSpaces(this char[] array)
{
int i = 0;
int num = array.Length - 1;
for (; i < array.Length && array[i].IsSpaceCharacter(); i++) {
}
while (num > i && array[num].IsSpaceCharacter()) {
num--;
}
return new string(array, i, 1 + num - i);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string[] SplitWithoutTrimming(this string str, char c)
{
return str.ToCharArray().SplitWithoutTrimming(c);
}
public static string[] SplitWithoutTrimming(this char[] chars, char c)
{
List<string> list = new List<string>();
int num = 0;
for (int i = 0; i < chars.Length; i++) {
if (chars[i] == c) {
if (i > num)
list.Add(new string(chars, num, i - num));
num = i + 1;
}
}
if (chars.Length > num)
list.Add(new string(chars, num, chars.Length - num));
return list.ToArray();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string[] SplitCommas(this string str)
{
return str.SplitWithTrimming(',');
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool HasHyphen(this string str, string value)
{
if (!str.Is(value)) {
if (str.Length > value.Length && str.StartsWith(value, StringComparison.Ordinal))
return str[value.Length] == '-';
return false;
}
return true;
}
public static string[] SplitSpaces(this string str)
{
List<string> list = new List<string>();
List<char> list2 = new List<char>();
char[] array = str.ToCharArray();
for (int i = 0; i <= array.Length; i++) {
if (i == array.Length || array[i].IsSpaceCharacter()) {
if (list2.Count > 0) {
string text = list2.ToArray().StripLeadingTrailingSpaces();
if (text.Length != 0)
list.Add(text);
list2.Clear();
}
} else
list2.Add(array[i]);
}
return list.ToArray();
}
public static string[] SplitWithTrimming(this string str, char c)
{
List<string> list = new List<string>();
List<char> list2 = new List<char>();
char[] array = str.ToCharArray();
for (int i = 0; i <= array.Length; i++) {
if (i == array.Length || array[i] == c) {
if (list2.Count > 0) {
string text = list2.ToArray().StripLeadingTrailingSpaces();
if (text.Length != 0)
list.Add(text);
list2.Clear();
}
} else
list2.Add(array[i]);
}
return list.ToArray();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int FromHex(this string s)
{
return int.Parse(s, NumberStyles.HexNumber);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int FromDec(this string s)
{
return int.Parse(s, NumberStyles.Integer);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string HtmlEncode(this string value, Encoding encoding)
{
return value;
}
public static string CssString(this string value)
{
StringBuilder stringBuilder = Pool.NewStringBuilder();
stringBuilder.Append('"');
if (!string.IsNullOrEmpty(value)) {
for (int i = 0; i < value.Length; i++) {
char c = value[i];
switch (c) {
case ' ':
throw new DomException(DomError.InvalidCharacter);
case '"':
case '\\':
stringBuilder.Append('\\').Append(c);
break;
default:
if (c.IsInRange(1, 31) || c == '{')
stringBuilder.Append('\\').Append(c.ToHex()).Append((i + 1 != value.Length) ? " " : "");
else
stringBuilder.Append(c);
break;
}
}
}
stringBuilder.Append('"');
return stringBuilder.ToPool();
}
public static string CssFunction(this string value, string argument)
{
return value + "(" + argument + ")";
}
public static string CssUrl(this string value)
{
string argument = value.CssString();
return FunctionNames.Url.CssFunction(argument);
}
public static string CssColor(this string value)
{
Color value2 = default(Color);
if (Color.TryFromHex(value, out value2))
return value2.ToString(null, CultureInfo.InvariantCulture);
return value;
}
public static string CssUnit(this string value, out float result)
{
if (!string.IsNullOrEmpty(value)) {
int num = value.Length;
while (!value[num - 1].IsDigit() && --num > 0) {
}
if (num > 0 && float.TryParse(value.Substring(0, num), NumberStyles.Any, CultureInfo.InvariantCulture, out result))
return value.Substring(num);
}
result = 0;
return null;
}
public static string UrlEncode(this byte[] content)
{
StringBuilder stringBuilder = Pool.NewStringBuilder();
for (int i = 0; i < content.Length; i++) {
char c = (char)content[i];
switch (c) {
case ' ':
stringBuilder.Append('+');
break;
default:
if (!c.IsAlphanumericAscii()) {
stringBuilder.Append('%').Append(content[i].ToString("X2"));
break;
}
goto case '*';
case '*':
case '-':
case '.':
case '_':
case '~':
stringBuilder.Append(c);
break;
}
}
return stringBuilder.ToPool();
}
public static byte[] UrlDecode(this string value)
{
MemoryStream memoryStream = new MemoryStream();
for (int i = 0; i < value.Length; i++) {
char c = value[i];
switch (c) {
case '+': {
byte value4 = 32;
memoryStream.WriteByte(value4);
break;
}
case '%': {
if (i + 2 >= value.Length)
throw new FormatException();
byte value3 = (byte)(16 * value[++i].FromHex() + value[++i].FromHex());
memoryStream.WriteByte(value3);
break;
}
default: {
byte value2 = (byte)c;
memoryStream.WriteByte(value2);
break;
}
}
}
return memoryStream.ToArray();
}
public static string NormalizeLineEndings(this string value)
{
if (!string.IsNullOrEmpty(value)) {
StringBuilder stringBuilder = Pool.NewStringBuilder();
bool flag = false;
foreach (char c in value) {
bool flag2 = c == '\n';
if (flag && !flag2)
stringBuilder.Append('\n');
else if (!flag & flag2) {
stringBuilder.Append('\r');
}
flag = (c == '\r');
stringBuilder.Append(c);
}
if (flag)
stringBuilder.Append('\n');
return stringBuilder.ToPool();
}
return value;
}
public static string ToEncodingType(this string encType)
{
if (!encType.Isi(MimeTypeNames.Plain) && !encType.Isi(MimeTypeNames.MultipartForm) && !encType.Isi(MimeTypeNames.ApplicationJson))
return MimeTypeNames.UrlencodedForm;
return encType;
}
}
}