topical media & game development

talk show tell print

game-xna-intro-XnaTetris-Helpers-StringHelper.cs / cs



  // Project: XnaTetris, File: StringHelper.cs
  // Namespace: XnaTetris.Helpers, Class: StringHelper
  // Creation date: 22.11.2004 09:51
  // Last modified: 19.01.2006 04:10
  // Generated with Commenter by abi.exDream.com
  
  #region Using directives
  if DEBUG
  //using NUnit.Framework;
  endif
  using System;
  using System.Text;
  using System.Collections;
  using System.Collections.Specialized;
  using System.Globalization;
  using System.Diagnostics;
  using System.Collections.Generic;
  #endregion
  
  namespace XnaTetris.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 class StringHelper { #region Constants public const string NewLine = "\r\n"; #endregion

                  #region Constructor (it is not allowed to instantiate)
  
<summary> Don't allow instantiating this class. </summary> private StringHelper() { } // StringHelper() #endregion

                  #region Comparing, Counting and Extraction
  
<summary> Check if a string (s1, can be longer as s2) begins with another string (s2), only if s1 begins with the same string data as s2, true is returned, else false. The string compare is case insensitive. </summary> static public bool BeginsWith(string s1, string s2) { return String.Compare(s1, 0, s2, 0, s2.Length, true, CultureInfo.CurrentCulture) == 0; } // BeginsWith(s1, s2)

  
<summary> Helps to compare strings, uses case insensitive comparison. String.Compare is also gay because we have always to check for == 0. </summary> static public bool Compare(string s1, string s2) { return String.Compare(s1, s2, true, CultureInfo.CurrentCulture) == 0; } // Compare(s1, s2)

  
<summary> Helps to compare strings, uses case insensitive comparison. String.Compare is also gay because we have always to check for == 0. This overload allows multiple strings to be checked, if any of them matches we are good to go (e.g. ("hi", {"hey", "hello", "hi"}) will return true). </summary> static public bool Compare(string s1, string[] anyMatch) { if (anyMatch == null) throw new ArgumentNullException("anyMatch", "Unable to execute method without valid anyMatch array.");

                          foreach (string match in anyMatch)
                                  if (String.Compare(s1, match, true,
                                          CultureInfo.CurrentCulture) == 0)
                                          return true;
                          return false;
                  } // Compare(s1, anyMatch)
  
  
<summary> Is a specific name in a list of strings? </summary> static public bool IsInList( string name, ArrayList list, bool ignoreCase) { if (list == null) throw new ArgumentNullException("list", "Unable to execute method without valid list.");

                          foreach (string listEntry in list)
                                  if (String.Compare(name, listEntry, ignoreCase,
                                          CultureInfo.CurrentCulture) == 0)
                                          return true;
                          return false;
                  } // IsInList(name, list, ignoreCase)
  
  
<summary> Is a specific name in a list of strings? </summary> static public bool IsInList( string name, string[] list, bool ignoreCase) { if (list == null) throw new ArgumentNullException("list", "Unable to execute method without valid list.");

                          foreach (string listEntry in list)
                                  if (String.Compare(name, listEntry, ignoreCase,
                                          CultureInfo.CurrentCulture) == 0)
                                          return true;
                          return false;
                  } // IsInList(name, list, ignoreCase)
  
  
<summary> Count words in a text (words are only separated by ' ' (spaces)) </summary> static public int CountWords(string text) { if (text == null) throw new ArgumentNullException("text", "Unable to execute method without valid text.");

                          return text.Split(new char[] { ' ' }).Length;
                  } // CountWords(text)
  
  
<summary> Compare char case insensitive </summary> <param name="c1">C 1</param> <param name="c2">C 2</param> <returns>Bool</returns> public static bool CompareCharCaseInsensitive(char c1, char c2) { return char.ToLower(c1) == char.ToLower(c2); // Another way (slower): // return String.Compare("" + c1, "" + c2, true) == 0; } // CompareCharCaseInsensitive(c1, c2)

  
<summary> Get last word </summary> <param name="text">Text</param> <returns>String</returns> public static string GetLastWord(string text) { if (text == null) throw new ArgumentNullException("text", "Unable to execute method without valid text.");

                          string[] words = text.Split(new char[] { ' ' });
                          if (words.Length > 0)
                                  return words[words.Length - 1];
                          return text;
                  } // GetLastWord(text)
  
  
<summary> Remove last word </summary> <param name="text">Text</param> <returns>String</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); } // RemoveLastWord(text)

  
<summary> Get all spaces and tabs at beginning </summary> <param name="text">Text</param> <returns>String</returns> static public string GetAllSpacesAndTabsAtBeginning(string text) { if (text == null) throw new ArgumentNullException("text", "Unable to execute method without valid text.");

                          StringBuilder ret = new StringBuilder();
                          for (int pos = 0; pos < text.Length; pos++)
                          {
                                  if (text[pos] == ' ' ||
                                          text[pos] == '\t')
                                          ret.Append(text[pos]);
                                  else
                                          break;
                          } // for (pos)
                          return ret.ToString();
                  } // GetAllSpacesAndTabsAtBeginning(text)
  
  
<summary> Get tab depth </summary> <param name="text">Text</param> <returns>Int</returns> static public int GetTabDepth(string text) { for (int textPos = 0; textPos < text.Length; textPos++) if (text[textPos] != '\t') return textPos; return text.Length; } // GetTabDepth(text)

  
<summary> Check string word length </summary> public static string CheckStringWordLength( string originalText, int maxLength) { if (originalText == null) throw new ArgumentNullException("originalText", "Unable to execute method without valid text.");

                          string[] splitted = originalText.Split(new char[] { ' ' });
                          string ret = "";
                          foreach (string word in splitted)
                          {
                                  if (word.Length <= maxLength)
                                          ret += word + " ";
                                  else
                                  {
                                          for (int i = 0; i < word.Length / maxLength; i++)
                                                  ret += word.Substring(i * maxLength, maxLength) + " ";
                                  } // else
                          } // foreach (word, splitted)
                          return ret.TrimEnd();
                  } // CheckStringWordLength(originalText, maxLength)
                  #endregion
  
                  #region String contains (for case insensitive compares)
  
<summary> Is searchName contained in textToCheck, will check case insensitive, for a normal case sensitive test use textToCheck.Contains(searchName) </summary> <param name="textToCheck">Text to check</param> <param name="searchName">Search name</param> <returns>Bool</returns> public static bool Contains(string textToCheck, string searchName) { return textToCheck.ToLower().Contains(searchName.ToLower()); } // Contains(textToCheck, searchName)

  
<summary> Is any of the names in searchNames contained in textToCheck, will check case insensitive, for a normal case sensitive test use textToCheck.Contains(searchName). </summary> <param name="textToCheck">String to check</param> <param name="searchNames">Search names</param> <returns>Bool</returns> public static bool Contains(string textToCheck, string[] searchNames) { string stringToCheckLower = textToCheck.ToLower(); foreach (string name in searchNames) if (stringToCheckLower.Contains(name.ToLower())) return true; // Nothing found, no searchNames is contained in textToCheck return false; } // Contains(textToCheck, searchNames) #endregion

                  #region Write data
  
<summary> Returns a string with the array data, byte array version. </summary> static public string WriteArrayData(byte[] byteArray) { StringBuilder ret = new StringBuilder(); if (byteArray != null) for (int i = 0; i < byteArray.Length; i++) ret.Append((ret.Length == 0 ? "" : ", ") + byteArray[i].ToString(CultureInfo.InvariantCulture.NumberFormat)); return ret.ToString(); } // WriteArrayData(byteArray)

  
<summary> Returns a string with the array data, int array version. </summary> static public string WriteArrayData(int[] intArray) { StringBuilder ret = new StringBuilder(); if (intArray != null) for (int i = 0; i < intArray.Length; i++) ret.Append((ret.Length == 0 ? "" : ", ") + intArray[i].ToString(CultureInfo.InvariantCulture.NumberFormat)); return ret.ToString(); } // WriteArrayData(intArray)

  
<summary> Returns a string with the array data, general array version. </summary> static public string WriteArrayData(Array array) { StringBuilder ret = new StringBuilder(); if (array != null) for (int i = 0; i < array.Length; i++) ret.Append((ret.Length == 0 ? "" : ", ") + (array.GetValue(i) == null ? "null" : array.GetValue(i).ToString())); return ret.ToString(); } // WriteArrayData(array)

  
<summary> Returns a string with the array data, general array version with maxLength bounding (will return string with max. this number of entries). </summary> static public string WriteArrayData(Array array, int maxLength) { StringBuilder ret = new StringBuilder(); if (array != null) for (int i = 0; i < array.Length && i < maxLength; i++) ret.Append((ret.Length == 0 ? "" : ", ") + array.GetValue(i).ToString()); return ret.ToString(); } // WriteArrayData(array, maxLength)

  
<summary> Returns a string with the array data, ArrayList version. </summary> static public string WriteArrayData(ArrayList array) { StringBuilder ret = new StringBuilder(); if (array != null) foreach (object obj in array) ret.Append((ret.Length == 0 ? "" : ", ") + obj.ToString()); return ret.ToString(); } // WriteArrayData(array)

  
<summary> Returns a string with the array data, CollectionBase version. </summary> static public string WriteArrayData(CollectionBase collection) { StringBuilder ret = new StringBuilder(); if (collection != null) foreach (object obj in collection) ret.Append((ret.Length == 0 ? "" : ", ") + obj.ToString()); return ret.ToString(); } // WriteArrayData(collection)

  if !XBOX360
  
<summary> Returns a string with the array data, StringCollection version. </summary> static public string WriteArrayData(StringCollection textCollection) { StringBuilder ret = new StringBuilder(); if (textCollection != null) foreach (string s in textCollection) ret.Append((ret.Length == 0 ? "" : ", ") + s); return ret.ToString(); } // WriteArrayData(textCollection) endif

  
<summary> Returns a string with the array data, enumerable class version. </summary> static public string WriteArrayData(IEnumerable enumerableClass) { StringBuilder ret = new StringBuilder(); if (enumerableClass != null) foreach (object obj in enumerableClass) ret.Append((ret.Length == 0 ? "" : ", ") + obj.ToString()); return ret.ToString(); } // WriteArrayData(enumerableClass)

  
<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 don't found any useful stuff. </summary> static public string WriteIntoSpaceString(string message, int spaces) { if (message == null) throw new ArgumentNullException("message", "Unable to execute method without valid text.");

                          // Msg is already that long or longer?
                          if (message.Length >= spaces)
                                  return message;
  
                          // Create string with number of specified spaces
                          char[] ret = new char[spaces];
  
                          // Copy data
                          int i;
                          for (i = 0; i < message.Length; i++)
                                  ret[i] = message[i];
                          // Fill rest with spaces
                          for (i = message.Length; i < spaces; i++)
                                  ret[i] = ' ';
  
                          // Return result
                          return new string(ret);
                  } // WriteIntoSpaceString(message, spaces)
  
  
<summary> Write Iso Date (Year-Month-Day) </summary> public static string WriteIsoDate(DateTime date) { return date.Year + "-" + date.Month.ToString("00") + "-" + date.Day.ToString("00"); } // WriteIsoDate(date)

  
<summary> Write Iso Date and time (Year-Month-Day Hour:Minute) </summary> public static string WriteIsoDateAndTime(DateTime date) { return date.Year + "-" + date.Month.ToString("00") + "-" + date.Day.ToString("00") + " " + date.Hour.ToString("00") + ":" + date.Minute.ToString("00"); } // WriteIsoDateAndTime(date)

  
<summary> Write internet time </summary> <param name="time">Time</param> <param name="daylightSaving">Daylight saving</param> <returns>String</returns> public static string WriteInternetTime( DateTime time, bool daylightSaving) { return "@" + ((float)((int)(time.ToUniversalTime().AddHours( daylightSaving ? 1 : 0).TimeOfDay. TotalSeconds * 100000 / (24 * 60 * 60))) / 100.0f).ToString( NumberFormatInfo.InvariantInfo); } // WriteInternetTime(time, daylightSaving) #endregion

                  #region Convert methods
  
<summary> Convert string data to int array, string must be in the form "1, 3, 8, 7", etc. WriteArrayData is the complementar function. </summary> <returns>int array, will be null if string is invalid!</returns> static public int[] ConvertStringToIntArray(string s) { // Invalid? if (s == null || s.Length == 0) return null;

                          string[] splitted = s.Split(new char[] { ' ' });
                          int[] ret = new int[splitted.Length];
                          for (int i = 0; i < ret.Length; i++)
                          {
                                  try
                                  {
                                          ret[i] = Convert.ToInt32(splitted[i]);
                                  } // try
                                  catch { } // ignore
                          } // for (i)
                          return ret;
                  } // ConvertStringToIntArray(str)
  
  
<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> <returns>float array, will be null if string is invalid!</returns> static public float[] ConvertStringToFloatArray(string s) { // Invalid? if (s == null || s.Length == 0) return null;

                          string[] splitted = s.Split(new char[] { ' ' });
                          float[] ret = new float[splitted.Length];
                          for (int i = 0; i < ret.Length; i++)
                          {
                                  try
                                  {
                                          ret[i] = Convert.ToSingle(splitted[i],
                                                  CultureInfo.InvariantCulture);
                                  } // try
                                  catch { } // ignore
                          } // for (i)
                          return ret;
                  } // ConvertStringToIntArray(str)
                  #endregion
  
                  #region File stuff
  
<summary> Extracts filename from full path+filename, cuts of extension if cutExtension is true. Can be also used to cut of directories from a path (only last one will remain). </summary> static public string ExtractFilename(string pathFile, bool cutExtension) { if (pathFile == null) return "";

                          // Update 2006-09-29: also checking for normal slashes, needed
                          // for support reading 3ds max stuff.
                          string[] fileName = pathFile.Split(new char[] { '\\', '/' });
                          if (fileName.Length == 0)
                          {
                                  if (cutExtension)
                                          return CutExtension(pathFile);
                                  return pathFile;
                          } // if (fileName.Length)
  
                          if (cutExtension)
                                  return CutExtension(fileName[fileName.Length - 1]);
                          return fileName[fileName.Length - 1];
                  } // ExtractFilename(pathFile, cutExtension)
  
  
<summary> Get directory of path+File, if only a path is given we will cut off the last sub path! </summary> static public string GetDirectory(string pathFile) { if (pathFile == null) return ""; int i = pathFile.LastIndexOf("\\"); if (i >= 0 && i < pathFile.Length) // Return directory return pathFile.Substring(0, i); // No sub directory found (parent of some dir is "") return ""; } // GetDirectory(pathFile)

  
<summary> Same as GetDirectory(): Get directory of path+File, if only a path is given we will cut of the last sub path! </summary> static public string CutOneFolderOff(string path) { // GetDirectory does exactly what we need! return GetDirectory(path); } // CutOneFolderOff(path)

  
<summary> Splits a path into all parts of its directories, e.g. "maps\\sub\\kekse" becomes {"maps\\sub\\kekse","maps\\sub","maps"} </summary> static public string[] SplitDirectories(string path) { ArrayList localList = new ArrayList(); localList.Add(path); do { path = CutOneFolderOff(path); if (path.Length > 0) localList.Add(path); } while (path.Length > 0);

                          return (string[])localList.ToArray(typeof(string));
                  } // SplitDirectories(path)
  
  
<summary> Remove first directory of path (if one exists). e.g. "maps\\mymaps\\hehe.map" becomes "mymaps\\hehe.map" Also used to cut first folder off, especially useful for relative paths. e.g. "maps\\test" becomes "test" </summary> static public string RemoveFirstDirectory(string path) { int i = path.IndexOf("\\"); if (i >= 0 && i < path.Length) // Return rest of path return path.Substring(i + 1); // No first directory found, just return original path return path; } // RemoveFirstDirectory(path)

  
<summary> Check if a folder is a direct sub folder of a main folder. True is only returned if this is a direct sub folder, not if it is some sub folder few levels below. </summary> static public bool IsDirectSubfolder(string subfolder, string mainFolder) { // First check if subFolder is really a sub folder of mainFolder if (subfolder != null && subfolder.StartsWith(mainFolder)) { // Same order? if (subfolder.Length < mainFolder.Length + 1) // Then it ain't a sub folder! return false; // Ok, now check if this is direct sub folder or some sub folder // of mainFolder sub folder string folder = subfolder.Remove(0, mainFolder.Length + 1); // Check if this is really a direct sub folder for (int i = 0; i < folder.Length; i++) if (folder[i] == '\\') // No, this is a sub folder of mainFolder sub folder return false; // Ok, this is a direct sub folder of mainFolder! return true; } // if (subFolder) // Not even any sub folder! return false; } // IsDirectSubFolder(subFolder, mainFolder)

  
<summary> Cut of extension, e.g. "hi.txt" becomes "hi" </summary> static public string CutExtension(string file) { if (file == null) return ""; int l = file.LastIndexOf('.'); if (l > 0) return file.Remove(l, file.Length - l); return file; } // CutExtension(file)

  
<summary> Get extension (the stuff behind that '.'), e.g. "test.bmp" will return "bmp" </summary> static public string GetExtension(string file) { if (file == null) return ""; int l = file.LastIndexOf('.'); if (l > 0 && l < file.Length) return file.Remove(0, l + 1); return ""; } // GetExtension(file) #endregion

                  #region String splitting and getting it back together
  
<summary> Performs basically the same job as String.Split, but does trim all parts, no empty parts are returned, e.g. "hi there" returns "hi", "there", String.Split would return "hi", "", "there". </summary> public static string[] SplitAndTrim(string text, char separator) { ArrayList ret = new ArrayList(); string[] splitted = text.Split(new char[] { separator }); foreach (string s in splitted) if (s.Length > 0) ret.Add(s); return (string[])ret.ToArray(typeof(string)); } // SplitAndTrim(text, separator)

  
<summary> Splits a multi line string to several strings and returns the result as a string array. Will also remove any \r, \n or space character at the end of each line! </summary> public static string[] SplitMultilineText(string text) { if (text == null) throw new ArgumentNullException("text", "Unable to execute method without valid text.");

                          ArrayList ret = new ArrayList();
                          // 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 char[] { '\n' });
                          string[] splitted2 = text.Split(new char[] { '\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);
                          } // foreach (s, splitted)
  
                          return (string[])ret.ToArray(typeof(string));
                  } // SplitMultiLineText(text)
  
  
<summary> Build string from lines </summary> <param name="lines">Lines</param> <param name="startLine">Start line</param> <param name="startOffset">Start offset</param> <param name="endLine">End line</param> <param name="endOffset">End offset</param> <param name="separator">Separator</param> <returns>String</returns> static public string BuildStringFromLines( string[] lines, int startLine, int startOffset, int endLine, int endOffset, string separator) { if (lines == null) throw new ArgumentNullException("lines", "Unable to execute method without valid lines.");

                          // 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);
                          } // for (lineNumber)
                          return builder.ToString();
                  } // BuildStringFromLines(lines, startLine, startOffset)
  
                  static public string BuildStringFromLines(
                          string[] lines, string separator)
                  {
                          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);
                          } // for (lineNumber)
                          return builder.ToString();
                  } // BuildStringFromLines(lines, separator)
  
  
<summary> Build string from lines </summary> <param name="lines">Lines</param> <returns>String</returns> static public string BuildStringFromLines(string[] lines) { return BuildStringFromLines(lines, NewLine); } // BuildStringFromLines(lines)

  
<summary> Build string from lines </summary> <param name="lines">Lines</param> <param name="startLine">Start line</param> <param name="endLine">End line</param> <param name="separator">Separator</param> <returns>String</returns> static public string BuildStringFromLines( string[] lines, int startLine, int endLine, string separator) { // 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);
                          } // for (lineNumber)
                          return builder.ToString();
                  } // BuildStringFromLines(lines, startLine, endLine)
  
  
<summary> Cut modes </summary> public enum CutMode { Begin, End, BothEnds } // enum CutMode

  
<summary> Maximum string length </summary> <param name="originalText">Original text</param> <param name="maxLength">Maximum length</param> <param name="cutMode">Cut mode</param> <returns>String</returns> public static string MaxStringLength(string originalText, int maxLength, CutMode cutMode) { if (originalText.Length <= maxLength) return originalText;

                          if (cutMode == CutMode.Begin)
                                  return originalText.Substring(
                                          originalText.Length - maxLength, maxLength);
                          else if (cutMode == CutMode.End)
                                  return originalText.Substring(0, maxLength);
                          else // logic: if ( cutMode == CutModes.BothEnds )
                                  return originalText.Substring(
                                          (originalText.Length - maxLength) / 2, maxLength);
                  } // MaxStringLength(originalText, maxLength, cutMode)
  
  
<summary> Get left part of everything to the left of the first occurrence of a character. </summary> public static string GetLeftPartAtFirstOccurence( string sourceText, char ch) { if (sourceText == null) throw new ArgumentNullException("sourceText", "Unable to execute this method without valid string.");

                          int index = sourceText.IndexOf(ch);
                          if (index == -1)
                                  return sourceText;
  
                          return sourceText.Substring(0, index);
                  } // GetLeftPartAtFirstOccurence(sourceText, ch)
  
  
<summary> Get right part of everything to the right of the first occurrence of a character. </summary> public static string GetRightPartAtFirstOccurrence( string sourceText, char ch) { if (sourceText == null) throw new ArgumentNullException("sourceText", "Unable to execute this method without valid string.");

                          int index = sourceText.IndexOf(ch);
                          if (index == -1)
                                  return "";
  
                          return sourceText.Substring(index + 1);
                  } // GetRightPartAtFirstOccurrence(sourceText, ch)
  
  
<summary> Get left part of everything to the left of the last occurrence of a character. </summary> public static string GetLeftPartAtLastOccurrence( string sourceText, char ch) { if (sourceText == null) throw new ArgumentNullException("sourceText", "Unable to execute this method without valid string.");

                          int index = sourceText.LastIndexOf(ch);
                          if (index == -1)
                                  return sourceText;
  
                          return sourceText.Substring(0, index);
                  } // GetLeftPartAtLastOccurrence(sourceText, ch)
  
  
<summary> Get right part of everything to the right of the last occurrence of a character. </summary> public static string GetRightPartAtLastOccurrence( string sourceText, char ch) { if (sourceText == null) throw new ArgumentNullException("sourceText", "Unable to execute this method without valid string.");

                          int index = sourceText.LastIndexOf(ch);
                          if (index == -1)
                                  return sourceText;
  
                          return sourceText.Substring(index + 1);
                  } // GetRightPartAtLastOccurrence(sourceText, ch)
  
  
<summary> Create password string </summary> <param name="originalText">Original text</param> <returns>String</returns> public static string CreatePasswordString(string originalText) { if (originalText == null) throw new ArgumentNullException("originalText", "Unable to execute this method without valid string.");

                          string passwordString = "";
                          for (int i = 0; i < originalText.Length; i++)
                                  passwordString += "*";
                          return passwordString;
                  } // CreatePasswordString(originalText)
  
  
<summary> Helper function to convert letter to lowercase. Could someone tell me the reason why there is no function for that in char? </summary> public static char ToLower(char letter) { return (char)letter.ToString().ToLower( CultureInfo.InvariantCulture)[0]; } // ToLower(letter)

  
<summary> Helper function to convert letter to uppercase. Could someone tell me the reason why there is no function for that in char? </summary> public static char ToUpper(char letter) { return (char)letter.ToString().ToUpper( CultureInfo.InvariantCulture)[0]; } // ToUpper(letter)

  
<summary> Helper function to check if this is an lowercase letter. </summary> public static bool IsLowercaseLetter(char letter) { return letter == ToLower(letter); } // IsLowercaseLetter(letter)

  
<summary> Helper function to check if this is an uppercase letter. </summary> public static bool IsUppercaseLetter(char letter) { return letter == ToUpper(letter); } // IsUppercaseLetter(letter)

  
<summary> Helper function for SplitFunctionNameToWordString to detect abbreviations in the function name </summary> private static int GetAbbreviationLengthInFunctionName( string functionName, int startPos) { StringBuilder abbreviation = new StringBuilder(); // Go through string until we reach a lower letter or it ends for (int pos = startPos; pos < functionName.Length; pos++) { // Quit if its not an uppercase letter if (StringHelper.IsUppercaseLetter(functionName[pos]) == false) break; // Else just add letter abbreviation.Append(functionName[pos]); } // for (pos)

                          // Abbreviation has to be at least 2 letters long.
                          if (abbreviation.Length >= 2)
                          {
                                  // If not at end of functionName, last letter belongs to next name,
                                  // e.g. "TW" is not a abbreviation in "HiMrTWhatsUp",
                                  // "AB" isn't one either in "IsABall",
                                  // but "PQ" is in "PQList" and "AB" is in "MyAB"
                                  if (startPos + abbreviation.Length >= functionName.Length)
                                          // Ok, then return full abbreviation length
                                          return abbreviation.Length;
                                  // Else return length - 1 because of next word
                                  return abbreviation.Length - 1;
                          } // if (abbreviation.Length)
  
                          // No Abbreviation, just return 1
                          return 1;
                  } // GetAbbreviationLengthInFunctionName(functionName, startPos)
  
  
<summary> Checks if letter is space ' ' or any punctuation (. , : ; ' " ! ?) </summary> public static bool IsSpaceOrPunctuation(char letter) { return letter == ' ' || letter == '.' || letter == ',' || letter == ':' || letter == ';' || letter == '\'' || letter == '\"' || letter == '!' || letter == '?' || letter == '*'; } // IsSpaceOrPunctuation(letter)

  
<summary> Splits a function name to words, 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> public static string SplitFunctionNameToWordString(string functionName) { if (functionName == null || functionName.Length == 0) return "";

                          string ret = "";
                          // Go through functionName and find big letters!
                          for (int pos = 0; pos < functionName.Length; pos++)
                          {
                                  char letter = functionName[pos];
                                  // First letter is always big!
                                  if (pos == 0 ||
                                          pos == 1 && StringHelper.IsUppercaseLetter(functionName[1]) &&
                                          StringHelper.IsUppercaseLetter(functionName[0]) ||
                                          pos == 2 && StringHelper.IsUppercaseLetter(functionName[2]) &&
                                          StringHelper.IsUppercaseLetter(functionName[1]) &&
                                          StringHelper.IsUppercaseLetter(functionName[0]))
                                          ret += StringHelper.ToUpper(letter);
                                          // Found uppercase letter?
                                  else if (StringHelper.IsUppercaseLetter(letter) &&
                                          //also support numbers and other symbols not lower/upper letter:
                                          //StringHelper.IsLowercaseLetter(letter) == false &&
                                          // But don't allow space or any punctuation (. , : ; ' " ! ?)
                                          StringHelper.IsSpaceOrPunctuation(letter) == false &&
                                          ret.EndsWith(" ") == false)
                                  {
                                          // Could be new word, but we have to check if its an abbreviation
                                          int abbreviationLength = GetAbbreviationLengthInFunctionName(
                                                  functionName, pos);
                                          // Found valid abbreviation?
                                          if (abbreviationLength > 1)
                                          {
                                                  // Then add it
                                                  ret += " " + functionName.Substring(pos, abbreviationLength);
                                                  // And advance pos (abbreviation is longer than 1 letter)
                                                  pos += abbreviationLength - 1;
                                          } // if (abbreviationLength)
                                                  // Else just add new word (in lower letter)
                                          else
                                                  ret += " " + StringHelper.ToLower(letter);
                                  } // else if
                                  else
                                          // Just add letter
                                          ret += letter;
                          } // for (pos)
                          return ret;
                  } // SplitFunctionNameToWordString(functionName)
                  #endregion
                  
                  #region Remove character
  
<summary> Remove character from text. </summary> <param name="text">Text</param> <param name="characterToBeRemoved">Character to be removed</param> public static void RemoveCharacter(ref string text, char characterToBeRemoved) { if (text == null) throw new ArgumentNullException("text", "Unable to execute method without valid text.");

                          if (text.Contains(characterToBeRemoved.ToString()))
                                  text = text.Replace(characterToBeRemoved.ToString(), "");
                  } // RemoveCharacter(text, characterToBeRemoved)
                  #endregion
  
                  #region Kb/mb name generator
  
<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> public static string WriteBigByteNumber( long bigByteNumber, string decimalSeperator) { if (bigByteNumber < 0) return "-" + WriteBigByteNumber(-bigByteNumber);

                          if (bigByteNumber <= 999)
                                  return bigByteNumber + " Bytes";
                          if (bigByteNumber <= 999 * 1024)
                          {
                                  double fKB = (double)bigByteNumber / 1024.0;
                                  return (int)fKB + decimalSeperator +
                                          ((int)(fKB * 100.0f) % 100).ToString("00") + " KB";
                          } // if
                          if (bigByteNumber <= 999 * 1024 * 1024)
                          {
                                  double fMB = (double)bigByteNumber / (1024.0 * 1024.0);
                                  return (int)fMB + decimalSeperator +
                                          ((int)(fMB * 100.0f) % 100).ToString("00") + " MB";
                          } // if
                          // this is very big ^^ will not fit into int
                          if (bigByteNumber <= 999L * 1024L * 1024L * 1024L)
                          {
                                  double fGB = (double)bigByteNumber / (1024.0 * 1024.0 * 1024.0);
                                  return (int)fGB + decimalSeperator +
                                          ((int)(fGB * 100.0f) % 100).ToString("00") + " GB";
                          } // if
                          //if ( num <= 999*1024*1024*1024*1024 )
                          //{
                          double fTB = (double)bigByteNumber / (1024.0 * 1024.0 * 1024.0 * 1024.0);
                          return (int)fTB + decimalSeperator +
                                  ((int)(fTB * 100.0f) % 100).ToString("00") + " TB";
                          //} // if
                  } // WriteBigByteNumber(num, decimalSeperator)
  
  
<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> public static string WriteBigByteNumber(long bigByteNumber) { string decimalSeperator = CultureInfo.CurrentCulture. NumberFormat.CurrencyDecimalSeparator; return WriteBigByteNumber(bigByteNumber, decimalSeperator); } // WriteBigByteNumber(num) #endregion

                  #region Try parse methods that are not available on the XBox360!
  
<summary> Is numeric float </summary> <param name="str">Str</param> <returns>Bool</returns> public static bool IsNumericFloat(string str) { return IsNumericFloat(str, CultureInfo.InvariantCulture.NumberFormat); } // IsNumericFloat(str)

  
<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> private 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++; } // if (numberFormat.CurrencyDecimalSeparator.IndexOf)

                                  // has float group seperators  ?
                                  if (numberFormat.CurrencyGroupSeparator.IndexOf(strInChars[i]) == 0)
                                  {
                                          hasGroupSeperator = true;
                                  } // if (numberFormat.CurrencyGroupSeparator.IndexOf)
                          } // for (int)
  
                          if (hasGroupSeperator)
                          {
                                  // If first digit is the group seperator or begins with 0,
                                  // there is something wrong, the group seperator 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];
                                  } // for (int)
                                  #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 (i)
                                  } // for (int)
                          } // if (hasGroupSeperator)
                          if (decimalSeperatorCount > 1)
                                  return false;
  
                          return true;
                  } // AllowOnlyOneDecimalPoint(str, numberFormat)
  
  
<summary> Checks if string is numeric float value </summary> <param name="str">Input string</param> <param name="numberFormat">Used number format, e.g. CultureInfo.InvariantCulture.NumberFormat</param> <returns>True if str can be converted to a float, false otherwise</returns> public static bool IsNumericFloat(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 indexs
                          bool retVal = false;
  
                          // If string is just 1 letter, don't allow it to be a sign
                          if (str.Length == 1 &&
                                  "+-.,".IndexOf(str[0]) >= 0)
                                  return false;
  
                          for (int i = 0; i < str.Length; i++)
                          {
                                  // For first indexchar
                                  char pChar =
                                          //char.Parse(str.Substring(i, 1));
                                          Convert.ToChar(str.Substring(i, 1));
  
                                  if (retVal)
                                          retVal = false;
  
                                  if ((!retVal) && (str.IndexOf(pChar) == 0))
                                  {
                                          retVal = ("+-.0123456789".IndexOf(pChar) >= 0) ? true : false;
                                  } // if ()
                                  // For middle characters
                                  if ((!retVal) && (str.IndexOf(pChar) > 0) &&
                                          (str.IndexOf(pChar) < (str.Length - 1)))
                                  {
                                          retVal = (",.0123456789".IndexOf(pChar) >= 0) ? true : false;
                                  } // if ()
                                  // For last characters
                                  if ((!retVal) && (str.IndexOf(pChar) == (str.Length - 1)))
                                  {
                                          retVal = ("+-,.0123456789".IndexOf(pChar) >= 0) ? true : false;
                                  } // if ()
  
                                  if (!retVal)
                                          break;
                          } // for (int)
  
                          return retVal;
                  } // IsNumericFloat(str, numberFormat)
  
  
<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="textToConvert">Text to convert</param> public static void TryToConvertToFloat( ref float value, string textToConvert) { TryToConvertToFloat(ref value, textToConvert, System.Globalization.NumberFormatInfo.InvariantInfo); } // TryToConvertToFloat(value, textToConvert)

  
<summary> Try to convert to float. Will not modify value if that does not work. </summary> <param name="value">Value</param> <param name="textToConvert">Text to convert</param> <param name="format">Format for converting</param> public static void TryToConvertToFloat( ref float value, string textToConvert, NumberFormatInfo format) { // Basically the same as float.TryParse(), but faster! if (IsNumericFloat(textToConvert, format)) { value = Convert.ToSingle(textToConvert, format); } // if (IsNumericFloat) } // TryToConvertToFloat(value, textToConvert, format)

  
<summary> Check if string is numeric integer. A decimal point is not accepted. </summary> <param name="str">String to check</param> public static bool IsNumericInt(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++;
                          } // foreach (ch in str)
  
                          // All fine, return true, this is a number!
                          return true;
                  } // IsNumericInt(str)
                  #endregion
  
                  #region Unit Testing
  if DEBUG
                  /*include NUnit.Framework for this
  
<summary> String helper tests </summary> //[TestFixture] public class StringHelperTests { <summary> Test is in list </summary> //[Test] public void TestIsInList() { Assert.IsTrue(IsInList("whats", new string[] { "hi", "whats", "up?" }, false)); Assert.IsFalse(IsInList("no way", new string[] { "omg", "no no", "there is no way!" }, false)); } // TestIsInList()

  
<summary> Test write array </summary> //[Test] public void TestWriteArray() { Assert.AreEqual( "3, 5, 10", WriteArrayData(new int[] { 3, 5, 10 })); Assert.AreEqual( "one, after, another", WriteArrayData(new string[] { "one", "after", "another" })); List<string> genericList = new List<string>(); genericList.Add("whats"); genericList.AddRange(new string[] { "going", "on" }); Assert.AreEqual( "whats, going, on", WriteArrayData(genericList)); } // TestWriteArray()

  
<summary> Test split string and combine again </summary> //[Test] public void TestSplitStringAndCombineAgain() { string testText = @"using System;

  namespace TestVs2003
  {
          public class Form1 : System.Windows.Forms.Form
          {
  
<summary> The main entry point for the application. </summary> [STAThread] static void Main() { Application.Run(new Form1()); } } }"; // Test splitting lines and combine them back together string[] lines = SplitMultilineText(testText); Assert.IsTrue(lines.Length > 0, "no lines were returned"); string reconstructedText = BuildStringFromLines(lines); Assert.AreEqual(testText, reconstructedText, "testText is not equal to reconstructedText");

                                  // Also test other functions
                                  string[] words = SplitAndTrim(testText, ' ');
                                  Assert.AreEqual(words.Length, CountWords(testText), "words.Length");
                                  Assert.AreEqual(testText, BuildStringFromLines(words, " "));
                                  // Call with some invalid values
                                  BuildStringFromLines(words, 1, -3, 4, 6, " ");
                                  BuildStringFromLines(words, 1, 3, 400, 6, " ");
                                  BuildStringFromLines(words, 1, 3, 4, 600, " ");
                                  // Check is we can build a part back together
                                  // Check if we can build a part back together
                                  Assert.AreEqual(
                                          testText.Substring(10, 20),
                                          BuildStringFromLines(lines, 0, 10, 2, 12, NewLine));
  
                                  // Get section code and check if we got everything right
                                  Assert.AreEqual(
                                          @"static void Main() 
                  {
                          Application.Run(new Form1());
                  }",
                                          BuildStringFromLines(lines, 10, 2, 13, 3, NewLine));
  
                                  // Also check if we change some line we still got the same
                                  // number of resulting lines.
                                  lines[13] += " // Test comment";
                                  Assert.AreEqual(lines.Length,
                                          SplitMultilineText(BuildStringFromLines(lines, NewLine)).Length);
                          } // TestSplitStringAndCombineAgain()
  
  
<summary> Test split multiline text </summary> //[Test] public void TestSplitMultilineText() { Assert.AreEqual(4, StringHelper.SplitMultilineText( @"test now an empty lie

  thats it").Length);
                                  // Test few empty lines
                                  Assert.AreEqual(6,
                                          StringHelper.SplitMultilineText(
                                          "hi\n\n\n\n\rthere\n").Length);
                                  // Test all combination of '\r' and '\n'
                                  Assert.AreEqual(2,
                                          StringHelper.SplitMultilineText(
                                          "test1" + '\r' + "test2").Length);
                                  Assert.AreEqual(2,
                                          StringHelper.SplitMultilineText(
                                          "test1" + '\n' + "test2").Length);
                                  Assert.AreEqual(2,
                                          StringHelper.SplitMultilineText(
                                          "test1" + "\n\r" + "test2").Length);
                                  Assert.AreEqual(2,
                                          StringHelper.SplitMultilineText(
                                          "test1" + "\r\n" + "test2").Length);
                                  // Also test if mixing normal "\n\r" with '\r' or '\n'
                                  Assert.AreEqual(3,
                                          StringHelper.SplitMultilineText(
                                          "test1" + '\n' + "" + '\r' + "test2" +
                                          '\r' + "test3").Length);
                                  Assert.AreEqual(3,
                                          StringHelper.SplitMultilineText(
                                          "test1" + '\n' + "" + '\r' + "test2" +
                                          '\n' + "test3").Length);
                          } // TestSplitMultilineText()
  
  
<summary> Test get tab depth </summary> //[Test] public void TestGetTabDepth() { Assert.AreEqual(4, StringHelper.GetTabDepth("\t\t\t\tWhats up?")); } // TestGetTabDepth()

  
<summary> Test is lowercase or uppercase letter </summary> //[Test] public void TestIsLowercaseOrUppercaseLetter() { Assert.AreEqual(true, IsLowercaseLetter('u')); Assert.AreEqual(true, IsUppercaseLetter('U')); // Well, numbers don't care if they upper or lower letters. Assert.AreEqual(true, IsLowercaseLetter('3')); Assert.AreEqual(true, IsUppercaseLetter('3')); } // TestIsLowercaseOrUppercaseLetter()

  
<summary> Test split function name to word string </summary> //[Test] public void TestSplitFunctionNameToWordString() { Assert.AreEqual( "Make damage on unit", SplitFunctionNameToWordString("MakeDamageOnUnit")); Assert.AreEqual( "This is a test", SplitFunctionNameToWordString("ThisIsATest")); Assert.AreEqual( "Create TCP listener", SplitFunctionNameToWordString("CreateTCPListener")); Assert.AreEqual( "Lower letter test", SplitFunctionNameToWordString("lowerLetterTest")); Assert.AreEqual( "Test 3D render function", SplitFunctionNameToWordString("Test3DRenderFunction")); Assert.AreEqual( "Check if CD is inserted", SplitFunctionNameToWordString("CheckIfCDIsInserted"));

                                  // Test with text that already got spaces (we expect same stuff
                                  // returned)
                                  Assert.AreEqual(
                                          "Ha ha, I have spaces already",
                                          SplitFunctionNameToWordString("ha ha, I have spaces already"));
                                  // Test mixed text
                                  Assert.AreEqual(
                                          "Hey what means What the hell?",
                                          SplitFunctionNameToWordString("Hey what means WhatTheHell?"));
  
                                  // Test some crazy strings to test if we get no exceptions
                                  SplitFunctionNameToWordString("\0\t\n\raoeu\b\t");
                                  SplitFunctionNameToWordString("@#%#@<RRROEU<YG SINDTBRPI\"'45453'");
                          } // TestSplitFunctionNameToWordString()
  
                          #region Test get extension
  
<summary> Test the GetExtension method. </summary> //[Test] public void TestGetExtension() { Assert.AreEqual("bmp", StringHelper.GetExtension("SomeBitmap.bmp")); Assert.AreEqual("xml", StringHelper.GetExtension("SomeApplication.config.xml")); } // TestGetExtension() #endregion } // class StringHelperTests

  
  endif
                  #endregion
          } // class StringHelper
  } // namespace XnaTetris.Helpers
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.