/Utilities/Helpers/StringHelper.cs
C# | 2249 lines | 1460 code | 141 blank | 648 comment | 247 complexity | 1997209697b7ee7278fd993a99206ecd MD5 | raw file
Possible License(s): Apache-2.0
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using System.Security.Cryptography;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading;
- using Delta.Utilities.Datatypes;
- using NUnit.Framework;
-
- namespace Delta.Utilities.Helpers
- {
- /// <summary>
- /// StringHelper: Provides additional or simplified string functions. This
- /// class does also offer a lot of powerful functions and allows complicated
- /// string operations. Easy functions at the beginning, harder ones later.
- /// </summary>
- public static class StringHelper
- {
- #region CutModes Enum
- /// <summary>
- /// Cut modes for MaxStringLength, cut at beginning of the string,
- /// at the end (default) or at both ends (for centered text maybe).
- /// </summary>
- public enum CutModes
- {
- /// <summary>
- /// Cut at beginning of text
- /// </summary>
- Begin,
-
- /// <summary>
- /// Cut at end of text
- /// </summary>
- End,
-
- /// <summary>
- /// Cut at both ends
- /// </summary>
- BothEnds,
-
- /// <summary>
- /// End string with ".." if we had to cut something off!
- /// Else the string is used normally.
- /// </summary>
- EndWithDots,
- }
- #endregion
-
- #region Constants
- /// <summary>
- /// New line, just "\r\n" (the default for Windows), used all over in
- /// StringHelper and always when multiline text is generated.
- /// </summary>
- public const string NewLine = "\r\n";
- #endregion
-
- #region Compare (Static)
- /// <summary>
- /// Helps to compare strings, uses case insensitive comparison.
- /// String.Compare is also ugly because we have always to check for == 0.
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="otherString">Other string to compare to</param>
- /// <returns>True if both strings are the same, ignoring the case</returns>
- public static bool Compare(this string stringToCheck, string otherString)
- {
- return String.Compare(stringToCheck, otherString,
- StringComparison.InvariantCultureIgnoreCase) == 0;
- }
-
- /// <summary>
- /// Is any of the names in searchNames the same as stringToCheck,
- /// will check case insensitive, for a normal case sensitive test
- /// use stringToCheck.Compare(searchName).
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="searchNames">Search names, can be a list or array</param>
- /// <returns>True if one of the searchNames was found</returns>
- public static bool Compare(this string stringToCheck,
- IEnumerable searchNames)
- {
- if (String.IsNullOrEmpty(stringToCheck))
- {
- return false;
- }
-
- foreach (string name in searchNames)
- {
- if (String.Compare(name, stringToCheck,
- StringComparison.InvariantCultureIgnoreCase) == 0)
- {
- return true;
- }
- }
-
- // Nothing found, no searchNames is contained in stringToCheck
- return false;
- }
- #endregion
-
- #region Split (Static)
- /// <summary>
- /// Split text with given separator and auto-trimming.
- /// </summary>
- /// <param name="text">Text</param>
- /// <param name="separator">Separator</param>
- /// <returns>Array of splitted strings, automatically trimmed</returns>
- public static string[] Split(this string text, string separator)
- {
- return Split(text, separator, true);
- }
-
- /// <summary>
- /// Split text with given separator and optional trimming.
- /// </summary>
- /// <param name="text">Text to split up</param>
- /// <param name="separator">Separator between splitted parts</param>
- /// <param name="trimSplittedParts">Trim splitted parts</param>
- /// <returns>Array of splitted strings</returns>
- public static string[] Split(this string text, string separator,
- bool trimSplittedParts)
- {
- // Validation
- if (String.IsNullOrEmpty(text))
- {
- return new string[0];
- }
-
- List<string> splittedParts = new List<string>();
- string[] rawSplittedParts = text.Split(new[]
- {
- separator
- },
- StringSplitOptions.None);
- for (int index = 0; index < rawSplittedParts.Length; index++)
- {
- string splitPart = rawSplittedParts[index];
- if (splitPart.Length > 0)
- {
- splittedParts.Add(trimSplittedParts
- ? splitPart.Trim()
- : splitPart);
- }
- }
- return splittedParts.ToArray();
- }
- #endregion
-
- #region IsNullOrWhiteSpace (Static)
- /// <summary>
- /// Checks if a string is 'null' or a contains of white space characters
- /// only.
- /// </summary>
- /// <param name="value"></param>
- /// <returns></returns>
- public static bool IsNullOrWhiteSpace(this string value)
- {
- return String.IsNullOrWhiteSpace(value);
- }
- #endregion
-
- #region SplitMultiLineText (Static)
- /// <summary>
- /// Splits a multi line string to several strings and returns the result as
- /// a string array.
- /// </summary>
- /// <param name="text">Text</param>
- /// <returns>the result as a string array</returns>
- public static string[] SplitMultiLineText(this string text)
- {
- // Validation
- if (IsNullOrWhiteSpace(text))
- {
- return new string[0];
- }
-
- // text.Split works only with \n strings, for \r\n, \n\r or any mixed
- // \r \n string we need special handling (its slow), try to avoid it.
- bool containsR = false;
- bool containsN = false;
- foreach (char ch in text)
- {
- if (ch == '\n')
- {
- containsN = true;
- if (containsR && containsN)
- {
- break;
- }
- }
- if (ch == '\r')
- {
- containsR = true;
- if (containsR && containsN)
- {
- break;
- }
- }
- }
-
- // No lines in this mofo? Then just return it!
- if (containsN == false &&
- containsR == false)
- {
- return new[]
- {
- text
- };
- }
- // First a quick check if this contains any \r chars
- else if (containsR == false)
- {
- // Just return the splitted by '\n' text
- return text.Split(new[]
- {
- '\n'
- });
- }
- else
- {
- List<string> ret = new List<string>();
- // Supports any format, only \r, only \n, normal \n\r,
- // crazy \r\n or even mixed \n\r with any format
- string[] splitted1 = text.Split(new[]
- {
- '\n'
- });
- string[] splitted2 = text.Split(new[]
- {
- '\r'
- });
- string[] splitted =
- splitted1.Length >= splitted2.Length
- ? splitted1
- : splitted2;
- foreach (string s in splitted)
- {
- // Never add any \r or \n to the single lines
- if (s.EndsWith("\r") ||
- s.EndsWith("\n"))
- {
- ret.Add(s.Substring(0, s.Length - 1));
- }
- else if (s.StartsWith("\n") ||
- s.StartsWith("\r"))
- {
- ret.Add(s.Substring(1));
- }
- else
- {
- ret.Add(s);
- }
- }
- return ret.ToArray();
- }
- }
- #endregion
-
- #region ForceTextIntoMultipleLines (Static)
- /// <summary>
- /// Just goes through the whole text and add new lines when reaching
- /// maxLineLength (will not keep lines below maxLineLength, but is good
- /// enough solution for now).
- /// </summary>
- /// <param name="inputText">Input text with any length</param>
- /// <param name="maxLineLength">Maximum line length after we should
- /// add newlines</param>
- /// <returns>Input text string with added new lines</returns>
- public static string ForceTextIntoMultipleLines(string inputText,
- int maxLineLength)
- {
- if (String.IsNullOrEmpty(inputText))
- {
- return "";
- }
-
- string ret = "";
- int currentLineLength = 0;
- char[] chars = inputText.ToCharArray();
- foreach (char letter in chars)
- {
- // Only split spaces!
- if (currentLineLength >= maxLineLength &&
- letter == ' ')
- {
- ret += "\n";
- currentLineLength = 0;
- }
- else
- {
- ret += letter;
- // If the text has already new lines, reset our line length counter!
- if (letter == '\n')
- {
- currentLineLength = 0;
- }
- else
- {
- currentLineLength++;
- }
- }
- }
- return ret;
- }
- #endregion
-
- #region IsNumericInt (Static)
- /// <summary>
- /// Check if string is numeric integer. A decimal point is not accepted.
- /// </summary>
- /// <param name="str">String to check</param>
- /// <returns>bool</returns>
- public static bool IsNumericInt(this string str)
- {
- // Can't be an int if string is not valid!
- if (String.IsNullOrEmpty(str))
- {
- return false;
- }
-
- // Go through every letter in str
- int strPos = 0;
- foreach (char ch in str)
- {
- // Only 0-9 are allowed
- if ("0123456789".IndexOf(ch) < 0 &&
- // Allow +/- for first char
- (strPos > 0 || (ch != '-' && ch != '+')))
- {
- return false;
- }
- strPos++;
- }
-
- // All fine, return true, this is a number!
- return true;
- }
- #endregion
-
- #region IsNumericFloat (Static)
- /// <summary>
- /// Is the given string a numeric float?
- /// </summary>
- /// <param name="str">Input string text to check</param>
- /// <returns>
- /// True if str is a numeric float (e.g. "0.0"), false otherwise.
- /// </returns>
- public static bool IsNumericFloat(this string str)
- {
- return IsNumericFloat(str, CultureInfo.InvariantCulture.NumberFormat);
- }
-
- /// <summary>
- /// Checks if string is numeric float value
- /// </summary>
- /// <param name="str">Input string text to check</param>
- /// <param name="numberFormat">Used number format, e.g.
- /// CultureInfo.InvariantCulture.NumberFormat</param>
- /// <returns>
- /// True if str can be converted to a float (e.g. "0.0"), false otherwise.
- /// </returns>
- public static bool IsNumericFloat(this string str,
- NumberFormatInfo numberFormat)
- {
- // Can't be a float if string is not valid!
- if (String.IsNullOrEmpty(str))
- {
- return false;
- }
-
- //not supported by Convert.ToSingle:
- //if (str.EndsWith("f"))
- // str = str.Substring(0, str.Length - 1);
-
- // Only 1 decimal point is allowed
- if (AllowOnlyOneDecimalPoint(str, numberFormat) == false)
- {
- return false;
- }
-
- // + allows in the first, last, don't allow in middle of the string
- // - allows in the first, last, don't allow in middle of the string
- // $ allows in the first, last, don't allow in middle of the string
- // , allows in the last, middle, don't allow in first char of the string
- // . allows in the first, last, middle, allows in all the indices
-
- // If string is just 1 letter, don't allow it to be a sign
- if (str.Length == 1 &&
- "+-$.,".IndexOf(str[0]) >= 0)
- {
- return false;
- }
-
- bool isFloat = false;
- for (int index = 0; index < str.Length; index++)
- {
- // For first index char
-
- char currentChar = char.Parse(str.Substring(index, 1));
-
- isFloat = false;
- if (str.IndexOf(currentChar) == 0)
- {
- isFloat = "+-$.0123456789".IndexOf(currentChar) >= 0;
- }
-
- // For middle characters
- if (isFloat == false &&
- str.IndexOf(currentChar) > 0 &&
- str.IndexOf(currentChar) < (str.Length - 1))
- {
- isFloat = ",.0123456789".IndexOf(currentChar) >= 0;
- }
-
- // For last characters
- if (isFloat == false &&
- str.IndexOf(currentChar) == (str.Length - 1))
- {
- isFloat = "+-$,.0123456789".IndexOf(currentChar) >= 0;
- }
-
- if (isFloat == false)
- {
- break;
- }
- }
-
- return isFloat;
- }
- #endregion
-
- #region AllowOnlyOneDecimalPoint (Static)
- /// <summary>
- /// Allow only one decimal point, used for IsNumericFloat.
- /// </summary>
- /// <param name="str">Input string to check</param>
- /// <param name="numberFormat">Used number format, e.g.
- /// CultureInfo.InvariantCulture.NumberFormat</param>
- /// <return>True if check succeeded, false otherwise</return>
- public static bool AllowOnlyOneDecimalPoint(string str,
- NumberFormatInfo numberFormat)
- {
- char[] strInChars = str.ToCharArray();
- bool hasGroupSeperator = false;
- int decimalSeperatorCount = 0;
- for (int i = 0; i < strInChars.Length; i++)
- {
- if (numberFormat.CurrencyDecimalSeparator.IndexOf(strInChars[i]) == 0)
- {
- decimalSeperatorCount++;
- }
-
- // has float group separators?
- if (numberFormat.CurrencyGroupSeparator.IndexOf(strInChars[i]) == 0)
- {
- hasGroupSeperator = true;
- }
- }
-
- if (hasGroupSeperator)
- {
- // If first digit is the group separator or begins with 0,
- // there is something wrong, the group separator is used as a comma.
- if (str.StartsWith(numberFormat.CurrencyGroupSeparator) ||
- strInChars[0] == '0')
- {
- return false;
- }
-
- // look only at the digits in front of the decimal point
- string[] splittedByDecimalSeperator = str.Split(
- numberFormat.CurrencyDecimalSeparator.ToCharArray());
-
- #region Invert the digits for modulo check
- // ==> 1.000 -> 000.1 ==> only after 3 digits
- char[] firstSplittedInChars = splittedByDecimalSeperator[0].ToCharArray();
- int arrayLength = firstSplittedInChars.Length;
- char[] firstSplittedInCharsInverted = new char[arrayLength];
- for (int i = 0; i < arrayLength; i++)
- {
- firstSplittedInCharsInverted[i] =
- firstSplittedInChars[arrayLength - 1 - i];
- }
- #endregion
-
- // group seperators are only allowed between 3 digits -> 1.000.000
- for (int i = 0; i < arrayLength; i++)
- {
- if (i % 3 != 0 &&
- numberFormat.CurrencyGroupSeparator.IndexOf(
- firstSplittedInCharsInverted[i]) == 0)
- {
- return false;
- }
- }
- }
- if (decimalSeperatorCount > 1)
- {
- return false;
- }
-
- return true;
- }
- #endregion
-
- #region GetLastWord (Static)
- /// <summary>
- /// Gets the last word of a text based on the given separator.
- /// </summary>
- /// <param name="text">Text</param>
- /// <param name="separator">Seperator</param>
- /// <returns>the last word of a text based on the given separator</returns>
- public static string GetLastWord(this string text, char separator)
- {
- // Validation check
- if (String.IsNullOrEmpty(text))
- {
- return "";
- }
-
- int seperatorIndex = text.LastIndexOf(separator);
- return (seperatorIndex != MathHelper.InvalidIndex)
- ? text.Substring(seperatorIndex + 1)
- : text;
- }
- #endregion
-
- #region GetClassName (Static)
- /// <summary>
- /// Get class name
- /// </summary>
- /// <param name="classType">Class type</param>
- /// <returns>class name</returns>
- public static string GetClassName(this Type classType)
- {
- //return "<" + GetLastWord(classType.ToString(), '.') + ">";
- //return "<" + classType.UnderlyingSystemType.Name + ">";
- return classType.UnderlyingSystemType.Name;
- }
- #endregion
-
- #region GetAllSpacesAndTabsAtBeginning (Static)
- /// <summary>
- /// Get all spaces and tabs at beginning
- /// </summary>
- /// <param name="text">Text</param>
- /// <returns>ret</returns>
- public static string GetAllSpacesAndTabsAtBeginning(this string text)
- {
- string ret = "";
- for (int pos = 0; pos < text.Length; pos++)
- {
- if (text[pos] == ' ' ||
- text[pos] == '\t')
- {
- ret += text[pos];
- }
- else
- {
- break;
- }
- }
- return ret;
- }
- #endregion
-
- #region GetInListContainsIndex (Static)
- /// <summary>
- /// Get Index of specific name in list. Case sensitive. Returns
- /// MathHelper.InvalidIndex if not found.
- /// </summary>
- /// <param name="name">Name</param>
- /// <param name="list">List</param>
- /// <param name="startIndex">
- /// Start index. Offset value to search from.</param>
- /// <returns>Index</returns>
- public static int GetInListContainsIndex(string name,
- string[] list, int startIndex)
- {
- if (startIndex >= list.Length)
- {
- return MathHelper.InvalidIndex;
- }
-
- for (int i = startIndex; i < list.Length; i++)
- {
- if (list[i].Contains(name))
- {
- return i;
- }
- }
-
- return MathHelper.InvalidIndex;
- }
- #endregion
-
- #region GetInListContainsSpecialIndex (Static)
- /// <summary>
- /// Get Index of specific name in list. Case sensitive. Returns
- /// MathHelper.InvalidIndex if not found.
- /// <para />
- /// Special Version: Ignores commented lines: "/*" ... "*/"; "//"
- /// <para />
- /// Ignores code in same line as a closing: "*/".
- /// </summary>
- /// <param name="name">Name</param>
- /// <param name="list">List</param>
- /// <param name="startIndex">
- /// Start index. Offset value to search from.</param>
- /// <returns>Int</returns>
- public static int GetInListContainsSpecialIndex(string name,
- string[] list, int startIndex)
- {
- if (startIndex >= list.Length)
- {
- return MathHelper.InvalidIndex;
- }
-
- // if in range of multi-line comments (/* ... */)
- bool ignoreLines = false;
-
- for (int i = startIndex; i < list.Length; i++)
- {
- string s = list[i];
- if (s.Contains("*/"))
- {
- ignoreLines = false;
- }
- else if (s.Contains("/*"))
- {
- // only ignoreLines if multi-Lines comment not out-commented
- ignoreLines = IsMultiBeginCommentValid(s);
- }
- else if (!ignoreLines &&
- s.Contains(name))
- {
- return i;
- }
- }
-
- return MathHelper.InvalidIndex;
- }
- #endregion
-
- #region IsMultiBeginCommentValid (Static)
- /// <summary>
- /// Returns if Multiline comment "/*" is not commented out,
- /// with "//".
- /// </summary>
- /// <param name="testString">Test string</param>
- /// <returns>True if this is a multiline comment, that is not commented
- /// out</returns>
- public static bool IsMultiBeginCommentValid(string testString)
- {
- int pos = testString.IndexOf("/*");
- int pos2 = testString.IndexOf("//");
-
- return (pos < pos2);
- }
- #endregion
-
- #region StartsWith (Static)
- /// <summary>
- /// Checks if a string starts with the given expression.
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="expression">Expression</param>
- /// <returns>True if the expression was found</returns>
- public static bool StartsWith(this string stringToCheck, string expression)
- {
- if (String.IsNullOrEmpty(stringToCheck))
- {
- return false;
- }
-
- return stringToCheck.ToLower().StartsWith(expression.ToLower());
- }
-
- /// <summary>
- /// Checks if a string starts with one of the strings in searchNames. This
- /// method will check case insensitive and is often used for file checks.
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="searchNames">Search names</param>
- /// <returns>True if one of the searchNames was found</returns>
- public static bool StartsWith(this string stringToCheck,
- string[] searchNames)
- {
- if (String.IsNullOrEmpty(stringToCheck))
- {
- return false;
- }
-
- string stringToCheckLower = stringToCheck.ToLower();
- foreach (string name in searchNames)
- {
- if (stringToCheckLower.StartsWith(name.ToLower()))
- {
- return true;
- }
- }
-
- // Nothing found, no searchNames is contained in stringToCheck
- return false;
- }
- #endregion
-
- #region EndsWith (Static)
- /// <summary>
- /// Checks if a string ends with the given expression.
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="expression">Expression</param>
- /// <returns>True if the expression was found</returns>
- public static bool EndsWith(this string stringToCheck, string expression)
- {
- if (String.IsNullOrEmpty(stringToCheck))
- {
- return false;
- }
-
- return stringToCheck.ToLower().EndsWith(expression.ToLower());
- }
-
- /// <summary>
- /// Checks if a string ends with one of the strings in searchNames. This
- /// method will check case insensitive and is often used for file checks.
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="searchNames">Search names</param>
- /// <returns>True if one of the searchNames was found</returns>
- public static bool EndsWith(this string stringToCheck,
- string[] searchNames)
- {
- if (String.IsNullOrEmpty(stringToCheck))
- {
- return false;
- }
-
- string stringToCheckLower = stringToCheck.ToLower();
- foreach (string name in searchNames)
- {
- if (stringToCheckLower.EndsWith(name.ToLower()))
- {
- return true;
- }
- }
-
- // Nothing found, no searchNames is contained in stringToCheck
- return false;
- }
- #endregion
-
- #region RemoveKeyWords (Static)
- /// <summary>
- /// Remove keywords from the stringToCheck. Useful to get rid of C#
- /// keywords like public, private, internal, etc. in source code lines.
- /// For example RemoveKeyWords("public static class Program",
- /// new string[] { "public", "private", "internal", "static" }) would
- /// return "class Program".
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="keywords">List of keywords to remove</param>
- /// <returns>Trimmed string without keywords</returns>
- public static string RemoveKeyWords(string stringToCheck,
- string[] keywords)
- {
- foreach (string keyword in keywords)
- {
- stringToCheck = stringToCheck.Replace(keyword, "");
- }
- return stringToCheck.Trim();
- }
- #endregion
-
- #region Contains (Static)
- /// <summary>
- /// Is searchName contained in stringToCheck, will check case insensitive,
- /// for a normal case sensitive test use stringToCheck.Contains(searchName)
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="searchName">Search name</param>
- /// <returns>True if stringToCheck contains searchName</returns>
- public static bool Contains(this string stringToCheck, string searchName)
- {
- if (String.IsNullOrEmpty(stringToCheck) ||
- String.IsNullOrEmpty(searchName))
- {
- return false;
- }
-
- return stringToCheck.ToLower().Contains(searchName.ToLower());
- }
-
- /// <summary>
- /// Is any of the names in searchNames contained in stringToCheck,
- /// will check case insensitive, for a normal case sensitive test
- /// use stringToCheck.Contains(searchName).
- /// </summary>
- /// <param name="stringToCheck">String to check</param>
- /// <param name="searchNames">Search names</param>
- /// <returns>True if one of the searchNames was found</returns>
- public static bool Contains(this string stringToCheck,
- string[] searchNames)
- {
- if (String.IsNullOrEmpty(stringToCheck))
- {
- return false;
- }
-
- string stringToCheckLower = stringToCheck.ToLower();
- foreach (string name in searchNames)
- {
- if (stringToCheckLower.Contains(name.ToLower()))
- {
- return true;
- }
- }
- // Nothing found, no searchNames is contained in stringToCheck
- return false;
- }
-
- /// <summary>
- /// Is any of the names in stringsToCheck contain searchName,
- /// will check case insensitive, for a normal case sensitive test
- /// use stringsToCheck.Contains(searchName).
- /// </summary>
- /// <param name="stringsToCheck">Array of strings to check</param>
- /// <param name="searchName">Search name</param>
- /// <returns>True if searchName was found</returns>
- public static bool Contains(List<string> stringsToCheck, string searchName)
- {
- if (stringsToCheck == null)
- {
- return false;
- }
-
- string searchNameLower = searchName.ToLower();
- foreach (string stringToCheck in stringsToCheck)
- {
- if (stringToCheck.ToLower().Contains(searchNameLower))
- {
- return true;
- }
- }
- // Nothing found, searchName is not contained in any stringsToCheck
- return false;
- }
- #endregion
-
- #region ToIntArray (Static)
- /// <summary>
- /// Convert string data to int array, string must be in the form
- /// "1, 3, 8, 7", etc. WriteArrayData is the complementary function.
- /// </summary>
- /// <param name="str">Input string</param>
- /// <returns>int array, will be null if string is invalid!</returns>
- public static int[] ToIntArray(this string str)
- {
- // Invalid?
- if (str == null ||
- str.Length == 0)
- {
- return null;
- }
-
- string[] splitted = str.Split(new[]
- {
- " ", ","
- },
- StringSplitOptions.RemoveEmptyEntries);
- List<int> ret = new List<int>();
- for (int i = 0; i < splitted.Length; i++)
- {
- int number;
- if (int.TryParse(splitted[i], out number))
- {
- ret.Add(number);
- }
- //try
- //{
- //ret.Add(Convert.ToInt32(splitted[i]));
- //} // try
- //catch { } // ignore
- }
- return ret.ToArray();
- }
- #endregion
-
- #region ToFloatArray (Static)
- /// <summary>
- /// Convert string data to float array, string must be in the form
- /// "1.5, 3.534, 8.76, 7.49", etc. WriteArrayData is the complementar
- /// function.
- /// </summary>
- /// <param name="s">s</param>
- /// <returns>float array, will be null if string is invalid!</returns>
- public static float[] ToFloatArray(this string s)
- {
- // Invalid?
- if (s == null ||
- s.Length == 0)
- {
- return null;
- }
-
- // Note: The input string must be well formed, else this won't work,
- // only 0-9, . and spaces are allowed!
- List<float> ret = new List<float>();
- float numberSoFar = 0.0f;
- // Decimal factor, goes to 10, 100, etc. and to 0.1, 0.01, etc.
- float decimalFactor = 1;
- bool afterPoint = false;
- bool negativeNumber = false;
- // Go through every letter
- for (int i = 0; i < s.Length; i++)
- {
- Char ch = s[i];
- // Is this a digit?
- if (ch >= '0' &&
- ch <= '9')
- {
- int digit = ch - '0';
- // Add either before or after decimal point
- if (afterPoint == false)
- {
- //Log.Write("before: numberSoFar=" + numberSoFar +
- // ", decimalFactor=" + decimalFactor);
- // Reverse engineering ^^
- numberSoFar = numberSoFar * decimalFactor + digit;
- decimalFactor = 10;
- //Log.Write("numberSoFar=" + numberSoFar +
- // ", decimalFactor=" + decimalFactor);
- }
- else
- {
- //Log.Write("digit before: numberSoFar=" + numberSoFar +
- // ", decimalFactor=" + decimalFactor);
- // Its a little bit easier for digits after the point
- numberSoFar += digit * decimalFactor;
- decimalFactor /= 10.0f;
- //Log.Write("digit: numberSoFar=" + numberSoFar +
- // ", decimalFactor=" + decimalFactor);
- }
- }
- else if (ch == '-')
- {
- negativeNumber = true;
- }
- else if (ch == '.')
- {
- decimalFactor = 0.1f;
- afterPoint = true;
- }
- else if (ch == ' ' ||
- ch == '\n')
- {
- // Flush
- if (negativeNumber)
- {
- numberSoFar = -numberSoFar;
- }
- ret.Add(numberSoFar);
- numberSoFar = 0;
- decimalFactor = 1;
- afterPoint = false;
- negativeNumber = false;
- }
- }
-
- // Add the last number we got
- if (negativeNumber)
- {
- numberSoFar = -numberSoFar;
- }
- ret.Add(numberSoFar);
-
- //Log.Write("s=" + s);
- //Log.Write("ret=" + ArrayHelper.Write(ret));
-
- return ret.ToArray();
- //*/
- }
-
- /// <summary>
- /// Convert string data to float array.
- /// <para />
- /// Note: The string numbers must be in the invariant number format.
- /// </summary>
- /// <param name="s">s</param>
- /// <returns>float array, will be null if string is invalid!</returns>
- public static float[] ToFloatArray(this string s, string separator = " ")
- {
- string[] textNumbers = Split(s, separator);
- float[] numbers = new float[textNumbers.Length];
- for (int index = 0; index < numbers.Length; index++)
- {
- numbers[index] = FromInvariantString(textNumbers[index], 0.0f);
- }
-
- return numbers;
- }
- #endregion
-
- #region ToInvariantString (Static)
- /// <summary>
- /// Write invariant string, which is helpful to write out floats, doubles
- /// or decimals in a invariant number format (not in german, spanish
- /// or whatever current language is running format, which can cause
- /// problems when importing the exported string number back).
- /// <para />
- /// Note: Not longer an extension method as it is annoying to type
- /// "To" for strings and intellisense brings this up first instead of
- /// the usual "ToString", which we almost always want instead.
- /// </summary>
- /// <param name="someObj">Some object, should be a number</param>
- /// <returns>Invariant string of the object</returns>
- public static string ToInvariantString(object someObj)
- {
- // No valid object given? Then don't return anything.
- if (someObj == null)
- {
- return "";
- }
-
- if (someObj is float)
- {
- return ((float)someObj).ToString(NumberFormatInfo.InvariantInfo);
- }
-
- if (someObj is double)
- {
- return ((double)someObj).ToString(NumberFormatInfo.InvariantInfo);
- }
-
- if (someObj is decimal)
- {
- return ((decimal)someObj).ToString(NumberFormatInfo.InvariantInfo);
- }
-
- // Dunno format, don't care (works fine for integers, enums, etc.)
- return someObj.ToString();
- }
-
- /// <summary>
- /// Extension to convert a float into an invariant string, which makes sure
- /// that the number format is always in the same for saving and parsing
- /// back to avoid problems because of the differences in the number format
- /// of the system languages.
- /// </summary>
- /// <param name="number">Any float number</param>
- /// <returns>Invariant string of the object</returns>
- public static string ToInvariantString(this float number)
- {
- return number.ToString(NumberFormatInfo.InvariantInfo);
- }
-
- /// <summary>
- /// Extension to convert a float into an invariant string, which makes sure
- /// that the number format is always in the same for saving and parsing
- /// back to avoid problems because of the differences in the number format
- /// of the system languages.
- /// </summary>
- /// <param name="number">Any float number</param>
- /// <param name="format">Custom format to use like "0.00"</param>
- /// <returns>Invariant string of the object</returns>
- public static string ToInvariantString(this float number, string format)
- {
- return number.ToString(format, NumberFormatInfo.InvariantInfo);
- }
-
- /// <summary>
- /// Extension to convert a double into an invariant string, which makes
- /// sure that the number format is always in the same for saving and
- /// parsing back to avoid problems because of the differences in the number
- /// format of the system languages.
- /// </summary>
- /// <param name="number">Any float number</param>
- /// <returns>Invariant string of the object</returns>
- public static string ToInvariantString(this double number)
- {
- return number.ToString(NumberFormatInfo.InvariantInfo);
- }
-
- /// <summary>
- /// Extension to convert a decimal to an invariant string, which makes sure
- /// that the number format is always in the same for saving and parsing
- /// back to avoid problems because of the differences in the number format
- /// of the system languages.
- /// </summary>
- /// <param name="number">Any float number</param>
- /// <returns>Invariant string of the object</returns>
- public static string ToInvariantString(this decimal number)
- {
- return number.ToString(NumberFormatInfo.InvariantInfo);
- }
- #endregion
-
- #region FromInvariantString (Static)
- /// <summary>
- /// Converts string to type, for example: integer, boolean or other stuff.
- /// </summary>
- /// <typeparam name="T">Type to convert into</typeparam>
- /// <param name="value">Input text containing value of T</param>
- /// <param name="defaultValue">The default value</param>
- /// <param name="extraWarningTextIfAnythingGoesWrong">A warning if anything
- /// goes wrong</param>
- /// <returns>Type or default value if failed</returns>
- public static T FromInvariantString<T>(this string value, T defaultValue,
- string extraWarningTextIfAnythingGoesWrong = "")
- {
- if (String.IsNullOrEmpty(value))
- {
- if (extraWarningTextIfAnythingGoesWrong != "")
- {
- Log.Warning(
- "The value is invalid, using the defaultValue '" + defaultValue +
- "' instead. " + extraWarningTextIfAnythingGoesWrong);
- }
- return defaultValue;
- }
-
- try
- {
- if (defaultValue is string)
- {
- // Note: It is already an string, but we can't cast it directly to T
- return (T)(Convert.ToString(value) as object);
- }
- else if (defaultValue is int)
- {
- return (T)(Convert.ToInt32(value) as object);
- }
- else if (defaultValue is double)
- {
- return (T)(Convert.ToDouble(value,
- CultureInfo.InvariantCulture) as object);
- }
- else if (defaultValue is float)
- {
- return (T)(Convert.ToSingle(value,
- CultureInfo.InvariantCulture) as object);
- }
- else if (defaultValue is bool)
- {
- return (T)(Convert.ToBoolean(value) as object);
- }
- else if (defaultValue is char)
- {
- return (T)(Convert.ToChar(value) as object);
- }
- else if (defaultValue is DateTime)
- {
- return (T)(Convert.ToDateTime(value) as object);
- }
- else if (defaultValue is Color)
- {
- return (T)(Color.FromString(value) as object);
- }
- else if (defaultValue is Point)
- {
- return (T)(Point.FromString(value) as object);
- }
- else if (defaultValue is Size)
- {
- return (T)(Size.FromString(value) as object);
- }
- else if (defaultValue is Vector)
- {
- return (T)(Vector.FromString(value) as object);
- }
- else if (defaultValue is Matrix)
- {
- return (T)(Matrix.FromString(value) as object);
- }
- else if (defaultValue is Rectangle)
- {
- return (T)(Rectangle.FromCommaString(value) as object);
- }
- else if (defaultValue is Enum)
- {
- return EnumHelper.ToEnum<T>(value);
- }
- else if (defaultValue != null)
- {
- // Try it the .NET way (won't work on some platforms, only fallback)
- // See http://predicatet.blogspot.com/2009/04/c-string-to-generic-type-conversion.html
- return (T)Convert.ChangeType(value, typeof(T));
- }
- else
- {
- Log.Warning(
- "Unsupported type " + defaultValue.GetType() + ", needs to be " +
- "implemented first! " + extraWarningTextIfAnythingGoesWrong);
- }
- }
- catch (Exception ex)
- {
- Log.Warning(
- "The value '" + value + "' couldn't be converted to a " +
- typeof(T) + ". " + extraWarningTextIfAnythingGoesWrong +
- " Reason:\n" + ex);
- }
-
- return defaultValue;
- }
- #endregion
-
- #region WriteIntoSpaceString (Static)
- /// <summary>
- /// Write into space string, useful for writing parameters without
- /// knowing the length of each string, e.g. when writing numbers
- /// (-1, 1.45, etc.). You can use this function to give all strings
- /// the same width in a table. Maybe there is already a string function
- /// for this, but I dont found any useful stuff.
- /// </summary>
- /// <param name="msg">Message to write</param>
- /// <param name="spaces">Number of spaces to fill</param>
- /// <returns>Same text as msg, but at least as long as spaces</returns>
- public static string WriteIntoSpaceString(this string msg, int spaces)
- {
- // Msg is already that long or longer?
- if (msg.Length >= spaces)
- {
- return msg;
- }
- // Create string with number of specified spaces
- char[] ret = new char[spaces];
- // Copy data
- int i;
- for (i = 0; i < msg.Length; i++)
- {
- ret[i] = msg[i];
- }
- // Fill rest with spaces
- for (i = msg.Length; i < spaces; i++)
- {
- ret[i] = ' ';
- }
- // Return result
- return new string(ret);
- }
- #endregion
-
- #region WriteInternetTime (Static)
- /// <summary>
- /// Write internet time
- /// </summary>
- public static string WriteInternetTime(
- this DateTime time, bool daylightSaving)
- {
- return "@" + (((int)(time.ToUniversalTime().AddHours(
- daylightSaving
- ? 1
- : 0).TimeOfDay.
- TotalSeconds * 100000 / (24 * 60 * 60))) / 100.0f).
- ToInvariantString();
- }
- #endregion
-
- #region WriteKbMbGbNumber (Static)
- /// <summary>
- /// Write bytes, KB, MB, GB, TB message.
- /// 1 KB = 1024 Bytes
- /// 1 MB = 1024 KB = 1048576 Bytes
- /// 1 GB = 1024 MB = 1073741824 Bytes
- /// 1 TB = 1024 GB = 1099511627776 Bytes
- /// E.g. 100 will return "100 Bytes"
- /// 2048 will return "2.00 KB"
- /// 2500 will return "2.44 KB"
- /// 1534905 will return "1.46 MB"
- /// 23045904850904 will return "20.96 TB"
- /// </summary>
- /// <param name="decimalSeperator">Decimal Separator</param>
- /// <param name="num">Number of bytes to write out</param>
- /// <returns>
- /// String with number of bytes in text form, e.g. "3.23 MB"
- /// </returns>
- public static string WriteKbMbGbNumber(long num,
- string decimalSeperator)
- {
- if (num < 0)
- {
- return "-" + WriteKbMbGbNumber(-num);
- }
- if (num <= 999)
- {
- return num + " Bytes";
- }
- if (num <= 999 * 1024)
- {
- double fKB = num / 1024.0;
- return (int)fKB + decimalSeperator +
- ((int)(fKB * 100.0f) % 100).ToString("00") + " KB";
- }
- if (num <= 999 * 1024 * 1024)
- {
- double fMB = num / (1024.0 * 1024.0);
- return (int)fMB + decimalSeperator +
- ((int)(fMB * 100.0f) % 100).ToString("00") + " MB";
- }
- // this is very big ^^ will not fit into int
- if (num <= 999L * 1024L * 1024L * 1024L)
- {
- double fGB = num / (1024.0 * 1024.0 * 1024.0);
- return (int)fGB + decimalSeperator +
- ((int)(fGB * 100.0f) % 100).ToString("00") + " GB";
- }
- //if ( num <= 999*1024*1024*1024*1024 )
- //{
- double fTB = num / (1024.0 * 1024.0 * 1024.0 * 1024.0);
- return (int)fTB + decimalSeperator +
- ((int)(fTB * 100.0f) % 100).ToString("00") + " TB";
- //} // if
- }
-
- /// <summary>
- /// Write bytes, KB, MB, GB, TB message.
- /// 1 KB = 1024 Bytes
- /// 1 MB = 1024 KB = 1048576 Bytes
- /// 1 GB = 1024 MB = 1073741824 Bytes
- /// 1 TB = 1024 GB = 1099511627776 Bytes
- /// E.g. 100 will return "100 Bytes"
- /// 2048 will return "2.00 KB"
- /// 2500 will return "2.44 KB"
- /// 1534905 will return "1.46 MB"
- /// 23045904850904 will return "20.96 TB"
- /// </summary>
- /// <param name="num">Number of bytes to write out</param>
- /// <returns>
- /// String with number of bytes in text form, e.g. "3.23 MB"
- /// </returns>
- public static string WriteKbMbGbNumber(long num)
- {
- string decimalSeperator = CultureInfo.CurrentCulture.
- NumberFormat.CurrencyDecimalSeparator;
- return WriteKbMbGbNumber(num, decimalSeperator);
- }
- #endregion
-
- #region Save (Static)
- /// <summary>
- /// Saves a string value to the given data stream writer. Since saving
- /// null is not allowed, we always store a string (empty string in this
- /// case). Loading the string can just be done with reader.ReadString().
- /// </summary>
- /// <param name="value">Value to save</param>
- /// <param name="dataWriter">Data writer</param>
- public static void Save(this string value, BinaryWriter dataWriter)
- {
- #region Validation
- if (dataWriter == null)
- {
- // Without a valid writer stream where can store the value into we
- // don't need to continue
- Log.Warning("Unable to save string, writer is not valid!");
- return;
- }
- #endregion
-
- dataWriter.Write(value ?? "");
- }
- #endregion
-
- #region BuildStringFromLines (Static)
- /// <summary>
- /// Build string from lines
- /// </summary>
- public static string BuildStringFromLines(
- this string[] lines,
- int startLine, int startOffset,
- int endLine, int endOffset,
- string separator)
- {
- // Check if all values are in range (correct if not)
- if (startLine >= lines.Length)
- {
- startLine = lines.Length - 1;
- }
- if (endLine >= lines.Length)
- {
- endLine = lines.Length - 1;
- }
- if (startLine < 0)
- {
- startLine = 0;
- }
- if (endLine < 0)
- {
- endLine = 0;
- }
- if (startOffset >= lines[startLine].Length)
- {
- startOffset = lines[startLine].Length - 1;
- }
- if (endOffset >= lines[endLine].Length)
- {
- endOffset = lines[endLine].Length - 1;
- }
- if (startOffset < 0)
- {
- startOffset = 0;
- }
- if (endOffset < 0)
- {
- endOffset = 0;
- }
-
- StringBuilder builder = new StringBuilder((endLine - startLine) * 80);
- for (int lineNumber = startLine; lineNumber <= endLine; lineNumber++)
- {
- if (lineNumber == startLine)
- {
- builder.Append(lines[lineNumber].Substring(startOffset));
- }
- else if (lineNumber == endLine)
- {
- builder.Append(lines[lineNumber].Substring(0, endOffset + 1));
- }
- else
- {
- builder.Append(lines[lineNumber]);
- }
-
- if (lineNumber != endLine)
- {
- builder.Append(separator);
- }
- }
- return builder.ToString();
- }
-
- /// <summary>
- /// Build string from lines
- /// </summary>
- /// <param name="lines">Input lines</param>
- /// <param name="separator">
- /// Separator between lines (by default NewLine).
- /// </param>
- /// <returns>
- /// Long text string with all the lines in in separated with NewLines.
- /// </returns>
- public static string BuildStringFromLines(this string[] lines,
- string separator = NewLine)
- {
- StringBuilder builder = new StringBuilder(lines.Length * 80);
- for (int lineNumber = 0; lineNumber < lines.Length; lineNumber++)
- {
- builder.Append(lines[lineNumber]);
- if (lineNumber != lines.Length - 1)
- {
- builder.Append(separator);
- }
- }
- return builder.ToString();
- }
-
- /// <summary>
- /// Build string from lines
- /// </summary>
- /// <param name="lines">Input lines, but only used partically</param>
- /// <param name="startLine">Start line to start writing out</param>
- /// <param name="endLine">End line to write</param>
- /// <param name="separator">
- /// Separator between lines (by default NewLine).
- /// </param>
- /// <returns>
- /// Long text string with all the lines in in separated with NewLines.
- /// </returns>
- public static string BuildStringFromLines(this string[] lines,
- int startLine, int endLine, string separator = NewLine)
- {
- // Check if all values are in range (correct if not)
- if (startLine < 0)
- {
- startLine = 0;
- }
- if (endLine < 0)
- {
- endLine = 0;
- }
- if (startLine >= lines.Length)
- {
- startLine = lines.Length - 1;
- }
- if (endLine >= lines.Length)
- {
- endLine = lines.Length - 1;
- }
-
- StringBuilder builder = new StringBuilder((endLine - startLine) * 80);
- for (int lineNumber = startLine; lineNumber <= endLine; lineNumber++)
- {
- builder.Append(lines[lineNumber]);
- if (lineNumber != endLine)
- {
- builder.Append(separator);
- }
- }
- return builder.ToString();
- }
- #endregion
-
- #region SplitAndTrim (Static)
- /// <summary>
- /// Performs basically the same job as String.Split, but does
- /// trim all parts, no empty parts are returned, e.g.
- /// "hi there" (thats 2 spaces) returns "hi", "there",
- /// String.Split would return "hi", "", "there".
- /// Or another example: "Flak, Shootgun".Split(',') would return
- /// "Flak" and " Shotgun", this function returns "Flak" and "Shotgun"
- /// </summary>
- /// <param name="text">Text</param>
- /// <param name="separator">Seperator</param>
- /// <returns>Array of strings</returns>
- public static string[] SplitAndTrim(this string text, char separator)
- {
- List<string> ret = new List<string>();
- string[] splitted = text.Split(new[]
- {
- separator
- });
- foreach (string s in splitted)
- {
- if (s.Length > 0)
- {
- ret.Add(s.Trim());
- }
- }
- return ret.ToArray();
- }
-
- /// <summary>
- /// Performs basically the same job as String.Split, but does
- /// trim all parts, no empty parts are returned, e.g.
- /// "hi there" (thats 2 spaces) returns "hi", "there",
- /// String.Split would return "hi", "", "there".
- /// Or another example: "Flak, Shootgun".Split(',') would return
- /// "Flak" and " Shotgun", this function returns "Flak" and "Shotgun"
- /// </summary>
- /// <param name="text">Text</param>
- /// <param name="separator">Separator</param>
- /// <returns>Array of strings</returns>
- public static string[] SplitAndTrim(this string text, string separator)
- {
- List<string> ret = new List<string>();
- string[] splitted = text.Split(new[]
- {
- separator
- },
- StringSplitOptions.None);
- foreach (string s in splitted)
- {
- if (s.Length > 0)
- {
- ret.Add(s.Trim());
- }
- }
- return ret.ToArray();
- }
-
- /// <summary>
- /// Performs basically the same job as String.Split, but does
- /// trim all parts, no empty parts are returned, e.g.
- /// "hi there" (thats 2 spaces) returns "hi", "there",
- /// String.Split would return "hi", "", "there".
- /// Or another example: "Flak, Shootgun".Split(',') would return
- /// "Flak" and " Shotgun", this function returns "Flak" and "Shotgun"
- /// </summary>
- /// <param name="text">Text</param>
- /// <param name="separators">Separators</param>
- /// <returns>Array of strings</returns>
- public static string[] SplitAndTrim(this string text, char[] separators)
- {
- if (String.IsNullOrEmpty(text))
- {
- return new string[0];
- }
-
- List<string> ret = new List<string>();
- string[] splitted = text.Split(separators);
- foreach (string s in splitted)
- {
- if (s.Trim().Length > 0)
- {
- ret.Add(s.Trim());
- }
- }
- return ret.ToArray();
- }
- #endregion
-
- #region IsMultiline (Static)
- /// <summary>
- /// Is text multiline checks if the string text has newline characters.
- /// </summary>
- /// <param name="text">Text to check.</param>
- /// <returns>True if the text is multiline, otherwise False.</returns>
- public static bool IsMultiline(this string text)
- {
- if (String.IsNullOrEmpty(text))
- {
- return false;
- }
- return text.Split(new[]
- {
- '\n', '\r'
- }).Length > 1;
- }
- #endregion
-
- #region HasMultipleWords (Static)
- /// <summary>
- /// Has multiple words checks if the string text, splitted at spaces,
- /// tabs or new lines, contains multiple words.
- /// </summary>
- /// <param name="text">Text to check.</param>
- /// <returns>True if the text has multiple words, otherwise False.</returns>
- public static bool HasMultipleWords(this string text)
- {
- if (String.IsNullOrEmpty(text))
- {
- return false;
- }
-
- return text.Split(new[]
- {
- ' ', '\t', '\n'
- }).Length > 1;
- }
- #endregion
-
- #region SplitWords (Static)
- /// <summary>
- /// Split words, the line can contain characters like whitespaces,
- /// newlines, spaces, commas, points or semicolons, everything is used
- /// to split words. Only words with at least one other characters are
- /// returned. Other delimiters characters: ~!@%^()-+=|\/{}[]:;"',?
- /// and the following ones (can't display here): amp, star and brackets.
- /// E.g. "He, she, it, yo man!" returns "He", "she", "it", "yo", "man".
- /// </summary>
- /// <param name="line">Line</param>
- /// <returns>Array of strings containing the splitted and trimmed words,
- /// can be an empty array if there were no words in the input text.
- /// </returns>
- public static string[] SplitWords(this string line)
- {
- string[] words = line.Split(new[]
- {
- ' ', '\t', '\n', '\r',
- '~', '!', '@', '%', '^', '&', '*', '(', ')',
- '-', '_', '+', '=', '|', '\\', '/', '{', '}', '[', ']', ':', ';',
- '"', '\'', '<', '>', ',', '?'
- },
- StringSplitOptions.RemoveEmptyEntries);
-
- List<string> ret = new List<string>();
- foreach (string word in words)
- {
- string trimmedWord = word.Trim();
- if (trimmedWord.Length > 0)
- {
- ret.Add(trimmedWord);
- }
- }
- return ret.ToArray();
- }
- #endregion
-
- #region LimitAllWordLengths (Static)
- /// <summary>
- /// Limit all word lengths
- /// </summary>
- /// <param name="textSnippet">Text snippet</param>
- /// <param name="maxWordLength">Maximum word length</param>
- /// <returns>String</returns>
- public static string LimitAllWordLengths(this string textSnippet,
- int maxWordLength)
- {
- string[] words = textSnippet.Split(new[]
- {
- ' ', ',', '<', '>'
- });
- foreach (string word in words)
- {
- if (word.Length > maxWordLength)
- {
- textSnippet =
- textSnippet.Replace(word, word.Substring(0, maxWordLength));
- }
- }
- return textSnippet;
- }
- #endregion
-
- #region MaxStringLength (Static)
- /// <summary>
- /// Return the same string back, but reduce it if it is too long. Often
- /// used for SQL databases table entries, which often only allow a certain
- /// string length for data fields.
- /// </summary>
- /// <param name="originalString">Original string</param>
- /// <param name="maxLength">Maximum length for the string</param>
- /// <param name="cutMode">Cut mode</param>
- /// <returns>
- /// String with the maximum length of maxLength characters.
- /// </returns>
- public static string MaxStringLength(this string originalString,
- int maxLength, CutModes cutMode)
- {
- if (String.IsNullOrEmpty(originalString))
- {
- return "";
- }
- if (originalString.Length <= maxLength)
- {
- return originalString;
- }
-
- if (cutMode == CutModes.Begin)
- {
- return originalString.Substring(
- originalString.Length - maxLength, maxLength);
- }
- else if (cutMode == CutModes.End)
- {
- return originalString.Substring(0, maxLength);
- }
- else if (cutMode == CutModes.EndWithDots)
- {
- if (maxLength < 2)
- {
- maxLength = 2;
- }
-
- return originalString.Substring(0, maxLength - 2).TrimEnd() + "..";
- }
- else // logic: if ( cutMode == CutModes.BothEnds )
- {
- return originalString.Substring(
- (originalString.Length - maxLength) / 2, maxLength);
- }
- }
- #endregion
-
- #region CreatePasswordString (Static)
- /// <summary>
- /// Create password string
- /// </summary>
- /// <param name="originalString">Original String</param>
- /// <returns>Password string</returns>
- public static string CreatePasswordString(this string originalString)
- {
- if (String.IsNullOrEmpty(originalString))
- {
- return "";
- }
- string passwordString = "";
- for (int i = 0; i < originalString.Length; i++)
- {
- passwordString += "*";
- }
- return passwordString;
- }
- #endregion
-
- #region SplitFunctionNameToWordString (Static)
- /// <summary>
- /// Splits a function name to words, was used for CR_Commenter in the past.
- /// E.g. "MakeDamageOnUnit" gets "Make damage on unit".
- /// Will also detect abbreviation like TCP and leave them
- /// intact, e.g. "CreateTCPListener" gets "Create TCP listener".
- /// </summary>
- /// <param name="functionString">Function String</param>
- /// <param name="upperLetterWords">Handle upper letter words</param>
- public static string SplitFunctionNameToWordString(
- this string functionString, bool upperLetterWords = false)
- {
- if (string.IsNullOrEmpty(functionString))
- {
- return "";
- }
-
- // Remove all underscores and dashes
- functionString = functionString.Replace("_", " ");
- functionString = functionString.Replace("-", " ");
-
- string ret = "";
- // Go through functionString and find big letters!
- for (int pos = 0; pos < functionString.Length; pos++)
- {
- char letter = functionString[pos];
- // First letter is always big!
- if (pos == 0 ||
- pos == 1 && functionString[1].IsUppercaseLetter() &&
- functionString[0].IsUppercaseLetter() ||
- pos == 2 && functionString[2].IsUppercaseLetter() &&
- functionString[1].IsUppercaseLetter() &&
- functionString[0].IsUppercaseLetter())
- {
- ret += letter.ToUpper();
- }
- // Found uppercase letter?
- else if (
- letter.IsUppercaseLetter() &&
- //also support numbers and other symbols not lower/upper letter:
- //StringHelper.IsLowercaseLetter(letter) == false &&
- // But don't allow space or any punctuation (. , : ; ' " ! ?)
- letter.IsSpaceOrPunctuation() == false &&
- ret.EndsWith(" ") == false)
- {
- // Could be new word, but we have to check if its an abbreviation
- int abbreviationLength = GetAbbreviationLengthInFunctionName(
- functionString, pos);
- // Found valid abbreviation?
- if (abbreviationLength > 1)
- {
- // Then add it
- ret += " " + functionString.Substring(pos, abbreviationLength);
- // And advance pos (abbreviation is longer than 1 letter)
- pos += abbreviationLength - 1;
- }
- // Else just add new word (in lower letter)
- else
- {
- if (upperLetterWords)
- {
- // Stay upper letter (looks better on web page)
- ret += " " + letter;
- }
- else
- {
- ret += " " + letter.ToLower();
- }
- }
- }
- else
- {
- // Just add letter
- ret += letter;
- }
- }
- return ret;
- }
- #endregion
-
- #region GetLeftPartAtFirstOccurence (Static)
- /// <summary>
- /// Get left part of everything to the left of the first occurrence of a
- /// character.
- /// </summary>
- /// <param name="ch">character</param>
- /// <param name="sourceString">Source String</param>
- /// <returns>String on the left side of ch</returns>
- public static string GetLeftPartAtFirstOccurence(
- this string sourceString, char ch)
- {
- int index = sourceString.IndexOf(ch);
- if (index == -1)
- {
- return sourceString;
- }
-
- return sourceString.Substring(0, index);
- }
- #endregion
-
- #region GetRightPartAtFirstOccurence (Static)
- /// <summary>
- /// Get right part of everything to the right of the first
- /// occurrence of a character.
- /// </summary>
- /// <param name="ch">character</param>
- /// <param name="sourceString">Source String</param>
- /// <returns>String on the right of ch</returns>
- public static string GetRightPartAtFirstOccurence(
- this string sourceString, char ch)
- {
- int index = sourceString.IndexOf(ch);
- if (index == -1)
- {
- return "";
- }
-
- return sourceString.Substring(index + 1);
- }
- #endregion
-
- #region GetLeftPartAtLastOccurence (Static)
- /// <summary>
- /// Get left part of everything to the left of the last
- /// occurrence of a character.
- /// </summary>
- /// <param name="ch">character</param>
- /// <param name="sourceString">Source String</param>
- /// <returns>String on the left side of ch</returns>
- public static string GetLeftPartAtLastOccurence(
- this string sourceString, char ch)
- {
- int index = sourceString.LastIndexOf(ch);
- if (index == -1)
- {
- return sourceString;
- }
-
- return sourceString.Substring(0, index);
- }
- #endregion
-
- #region GetRightPartAtLastOccurence (Static)
- /// <summary>
- /// Get right part of everything to the right of the last
- /// occurrence of a character.
- /// </summary>
- /// <param name="ch">character</param>
- /// <param name="sourceString">Source String</param>
- /// <returns>String on the right side of ch</returns>
- public static string GetRightPartAtLastOccurence(
- this string sourceString, char ch)
- {
- int index = sourceString.LastIndexOf(ch);
- if (index == -1)
- {
- return sourceString;
- }
-
- return sourceString.Substring(index + 1);
- }
- #endregion
-
- #region SearchTextBetweenChars (Static)
- /// <summary>
- /// Search text between chars, e.g. "hello" returns "ell" if
- /// firstChar is 'h' and lastChar is 'o'.
- /// </summary>
- /// <example>
- /// "ell" == SearchTextBetweenChars("hello", 'h', 'o');
- /// </example>
- /// <param name="sourceString">source string</param>
- /// <param name="firstChar">First char</param>
- /// <param name="lastChar">Last char</param>
- /// <returns>String</returns>
- public static string SearchTextBetweenChars(
- this string sourceString, char firstChar, char lastChar)
- {
- string ret = "";
- int firstIndex = sourceString.IndexOf(firstChar);
- if (firstIndex != -1)
- {
- firstIndex++;
- int lastIndex = sourceString.IndexOf(lastChar, firstIndex);
- if (lastIndex != -1)
- {
- ret = sourceString.Substring(firstIndex, lastIndex - firstIndex);
- }
- }
- return ret;
- }
- #endregion
-
- #region ToLower (Static)
- /// <summary>
- /// Helper function to convert letter to lowercase. Could someone
- /// tell me the reason why there is no function for that in char?
- /// </summary>
- /// <param name="letter">Letter</param>
- /// <returns>Letter in lower case</returns>
- public static char ToLower(this char letter)
- {
- return letter.ToString().ToLower()[0];
- }
- #endregion
-
- #region ToUpper (Static)
- /// <summary>
- /// Helper function to convert letter to uppercase. Could someone
- /// tell me the reason why there is no function for that in char?
- /// </summary>
- /// <param name="letter">Letter</param>
- /// <returns>Letter in upper case</returns>
- public static char ToUpper(this char letter)
- {
- return letter.ToString().ToUpper()[0];
- }
- #endregion
-
- #region IsLowercaseLetter (Static)
- /// <summary>
- /// Helper function to check if this is an lowercase letter.
- /// </summary>
- /// <param name="letter">Letter to check</param>
- /// <returns>True if this a lowercase letter</returns>
- public static bool IsLowercaseLetter(this char letter)
- {
- return letter == ToLower(letter);
- }
- #endregion
-
- #region IsUppercaseLetter (Static)
- /// <summary>
- /// Helper function to check if this is an uppercase letter.
- /// </summary>
- /// <param name="letter">Letter</param>
- /// <returns>True if this an uppercase letter</returns>
- public static bool IsUppercaseLetter(this char letter)
- {
- return letter == ToUpper(letter);
- }
- #endregion
-
- #region ToLowerJustFirstLetterUpper (Static)
- /// <summary>
- /// Convert text to lower case letters, make just first letter upper case
- /// </summary>
- /// <param name="someText">Some Text</param>
- /// <returns>String with just the first letter as uppercase</returns>
- public static string ToLowerJustFirstLetterUpper(this string someText)
- {
- // Make sure name is lower case, only first letter is upper case
- return ToUpper(someText[0]) + someText.ToLower().Substring(1);
- }
- #endregion
-
- #region IsSpaceOrPunctuation (Static)
- /// <summary>
- /// Checks if letter is space ' ' or any punctuation (. , : ; ' " ! ?)
- /// </summary>
- /// <param name="letter">Letter</param>
- /// <returns>True if this letter is space or any punctuation</returns>
- public static bool IsSpaceOrPunctuation(this char letter)
- {
- return
- letter == ' ' ||
- letter == '.' ||
- letter == ',' ||
- letter == ':' ||
- letter == ';' ||
- letter == '\'' ||
- letter == '\"' ||
- letter == '!' ||
- letter == '?' ||
- letter == '*';
- }
- #endregion
-
- #region GetAllIndicesOf (Static)
- /// <summary>
- /// Get all indices of the given string. Good to check how many occurances
- /// are in a string (e.g. how many special characters are in a code line).
- /// </summary>
- /// <param name="str">String to check</param>
- /// <param name="charValue">Char Value</param>
- /// <returns>Array of indices with the charValue we found</returns>
- public static int[] GetAllIndicesOf(this string str, char charValue)
- {
- List<int> indices = new List<int>();
- string s = str;
- int lastindex = 0;
- int count = 0;
-
- while (true)
- {
- s = s.Substring(lastindex);
- lastindex = s.IndexOf(charValue);
- if (lastindex < 0)
- {
- return indices.ToArray();
- }
-
- count += lastindex;
- indices.Add(count);
- lastindex++;
- count++;
- }
- }
-
- /// <summary>
- /// Get all indices of the given string. Good to check how many occurances
- /// are in a string (e.g. how many special characters are in a code line).
- /// </summary>
- /// <param name="str">String to check</param>
- /// <param name="stringValue">String Value</param>
- /// <returns>Array of indices with the stringValue we found</returns>
- public static int[] GetAllIndicesOf(this string str, string stringValue)
- {
- List<int> indices = new List<int>();
- string s = str;
- int lastindex = 0;
- int count = 0;
-
- while (true)
- {
- s = s.Substring(lastindex);
- lastindex = s.IndexOf(stringValue);
- if (lastindex < 0)
- {
- return indices.ToArray();
- }
-
- count += lastindex;
- indices.Add(count);
- lastindex++;
- count++;
- }
- }
- #endregion
-
- #region IsInList (Static)
- /// <summary>
- /// Is a specific name in a list of strings? This allows multiple strings
- /// to be checked, if any of them matches with the specified "name" (e.g.
- /// ("hi", {"hey", "hello", "hi"}) will return true). Does not do a
- /// contains check, the string has to be in the list.
- /// </summary>
- /// <param name="list">List</param>
- /// <param name="name">Name</param>
- /// <returns>Is name in any of the list entries</returns>
- public static bool IsInList(string name, IEnumerable<string> list)
- {
- return IsInList(name, list, true);
- }
-
- /// <summary>
- /// Is a specific name in a list of strings? This allows multiple strings
- /// to be checked, if any of them matches with the specified "name" (e.g.
- /// ("hi", {"hey", "hello", "hi"}) will return true). Does not do a
- /// contains check, the string has to be in the list.
- /// </summary>
- /// <param name="list">List</param>
- /// <param name="name">Name</param>
- /// <param name="ignoreCase">Ignore Case</param>
- /// <returns>Is name in any of the list entries</returns>
- public static bool IsInList(string name, IEnumerable<string> list,
- bool ignoreCase)
- {
- StringComparison compareMode = ignoreCase
- ? StringComparison.InvariantCultureIgnoreCase
- : StringComparison.InvariantCulture;
- foreach (string listEntry in list)
- {
- if (String.Compare(name, listEntry, compareMode) == 0)
- {
- return true;
- }
- }
-
- return false;
- }
- #endregion
-
- #region GetLastWord (Static)
- /// <summary>
- /// Get last word
- /// </summary>
- /// <param name="text">Text</param>
- /// <returns>Last word of Text</returns>
- public static string GetLastWord(string text)
- {
- return GetLastWord(text, new[]
- {
- ' '
- });
- }
-
- /// <summary>
- /// Get last word
- /// </summary>
- /// <param name="splitCharacters">Split Characters</param>
- /// <param name="text">Text</param>
- /// <returns>Last word of Text</returns>
- public static string GetLastWord(string text, char[] splitCharacters)
- {
- string[] words = text.Split(splitCharacters);
- if (words.Length > 0)
- {
- return words[words.Length - 1];
- }
- return text;
- }
- #endregion
-
- #region RemoveFirstWord (Static)
- /// <summary>
- /// Remove first word
- /// </summary>
- /// <param name="text">Text</param>
- /// <returns>String with the first word removed</returns>
- public static string RemoveFirstWord(string text)
- {
- string[] words = text.TrimStart().Split(new char[] { ' ' }, 2);
- if (words.Length > 0)
- {
- string firstWord = words[0];
- if (text == firstWord)
- {
- return "";
- }
- else if (firstWord.Length == 0 ||
- text.Length == 0 ||
- text.Length - firstWord.Length - 1 <= 0)
- {
- return text;
- }
- else
- {
- return text.TrimStart().Substring(firstWord.Length + 1);
- }
- }
- return text;
- }
- #endregion
-
- #region RemoveLastWord (Static)
- /// <summary>
- /// Remove last word
- /// </summary>
- /// <param name="text">Text</param>
- /// <returns>String with the last word removed</returns>
- public static string RemoveLastWord(string text)
- {
- string lastWord = GetLastWord(text);
- // Fix 2004-10-08: new length can be 0 for killing first word
- if (text == lastWord)
- {
- return "";
- }
- else if (lastWord.Length == 0 ||
- text.Length == 0 ||
- text.Length - lastWord.Length - 1 <= 0)
- {
- return text;
- }
- else
- {
- return text.Substring(0, text.Length - lastWord.Length - 1);
- }
- }
- #endregion
-
- #region TryToConvertToFloat (Static)
- /// <summary>
- /// Try to convert to float. Will not modify value if that does not work.
- /// This uses also always the invariant culture.
- /// </summary>
- /// <param name="value">Value</param>
- /// <param name="textToConv