-
Notifications
You must be signed in to change notification settings - Fork 75
Open
Description
Hello, The class pasted below causes the converter to enter an infinite loop. (However, 551 other classes were processed successfully, thank you for all your work!) I thought I would share the offending code so you could use it to investigate any potential bug, if desired.
Blake
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace CSharpTools.Tools
{
///
/// StringGroup
/// This class provides utilities for manipulating a StringGroup.
/// A StringGroup is a delimited string with a specific format, shown below.
/// These strings can contain a generically typed group of values.
///
/// The format is designed to include delimiter characters around every value.
/// That way, when searching for a specific value in a database, you can always include
/// the delimiter character on both sides of the string to explicitly specify the length
/// of the results.
///
/// The format is enclosed in braces so that multiple string groups could be included in a
/// single string if desired.
///
/// Values that contain the delimiter or brace characters will be escaped and unescaped as needed.
///
/// At the moment, this class does not modify new line or whitespace characters.
///
/// String format examples:
/// "{:1:2:3:4:}"
/// "{:Red:Green:Blue:Yellow:}"
/// </summary>
static public class StringGroup
{
static private string delimiter = ":";
/// <summary>
/// leftBrace
/// Contains the left brace character used by this class.
/// </summary>
static private string leftBrace = "{";
/// <summary>
/// rightBrace
/// Contains the right brace character used by this class.
/// </summary>
static private string rightBrace = "}";
/// <summary>
/// delimiterEscape
/// Contains the delimiter escape string used by this class.
/// </summary>
static private string delimiterEscape = ":";
/// <summary>
/// leftBraceEscape
/// Contains the left brace escape string used by this class.
/// </summary>
static private string leftBraceEscape = "{";
/// <summary>
/// rightBraceEscape
/// Contains the right brace escape string used by this class.
/// </summary>
static private string rightBraceEscape = "}";
const string emptyGroup = "{e}";
/// <summary>
/// GroupToList
/// This accepts a string that is formatted as a group, and returns a
/// strongly typed list that contains the elements of the string.
///
/// Example call:
/// List{int} numbersList = StringGroupToList{int}(numbersGroup);
/// </summary>
static public List<T> GroupToList<T>(string stringGroup)
{
if (stringGroup == emptyGroup) { return new List<T>(); }
List<T> result = new List<T>();
stringGroup = Use.SafeSubString(stringGroup, 1, stringGroup.Length - 2);
string[] stringArray = stringGroup.Split(delimiter[0]);
int stop = stringArray.Length - 1;
for (int i = 1; i < stop; ++i)
{
string element = stringArray[i];
element = element.Replace(delimiterEscape, delimiter);
element = element.Replace(leftBraceEscape, leftBrace);
element = element.Replace(rightBraceEscape, rightBrace);
dynamic elementDynamic;
Type parameter = typeof(T);
if (parameter == typeof(int))
{
try { elementDynamic = Convert.ToInt32(element); }
catch (Exception)
{ throw new Exception("Could not convert group element to integer in function StringGroupToList()."); }
}
else if (parameter == typeof(long))
{
try { elementDynamic = Convert.ToInt64(element); }
catch (Exception)
{ throw new Exception("Could not convert group element to long in function StringGroupToList()."); }
}
else
{
elementDynamic = element;
}
result.Add(elementDynamic);
}
return result;
}
/// <summary>
/// GroupFromList
/// Returns a formatted string containing all of the list elements.
/// The returned string is suitable for storing in a database record, and
/// can also be converted back into a list through the reverse function.
/// Any null values in the list are included as empty strings.
/// Any values containing the pipe character will be escaped.
/// </summary>
static public string GroupFromList<T>(List<T> list)
{
if (list.Count == 0) { return emptyGroup; }
string result = leftBrace + delimiter;
foreach (T elementGeneric in list)
{
string element;
try { element = Convert.ToString(elementGeneric); }
catch (Exception)
{ throw new Exception("Could not convert list element to a string in function StringGroupFromList()."); }
element = element.Replace(delimiter, delimiterEscape);
element = element.Replace(rightBrace, rightBraceEscape);
element = element.Replace(leftBrace, leftBraceEscape);
result += element + delimiter;
}
return result + rightBrace;
}
static public string GroupFromParameters(params object[] values)
{
return GroupFromList<object>(values.ToList<object>());
}
static public string ClusterFromListOfGroups(List<string> listOfStringGroupsOrClusters)
{
string result = "";
foreach (string group in listOfStringGroupsOrClusters)
{
result += group;
}
return result;
}
static public List<string> ClusterToListOfGroups(string groupCluster)
{
if (groupCluster == null || groupCluster.Trim().Length == 0)
return new List<string>();
string startSequence = leftBrace + delimiter;
string endSequence = delimiter + rightBrace;
groupCluster = groupCluster.Trim();
if ((!groupCluster.StartsWith(emptyGroup)) &&
((!groupCluster.StartsWith(startSequence)) || (!groupCluster.EndsWith(endSequence))))
{
throw new Exception("ClusterToListOfStringGroups(), Invalid string input was given.");
}
List<string> result = new List<string>();
int searchPosition = 0;
while (searchPosition < groupCluster.Length)
{
int emptyStartIndex = groupCluster.IndexOf(emptyGroup, searchPosition);
int startIndex = groupCluster.IndexOf(startSequence, searchPosition);
int endIndex = groupCluster.IndexOf(endSequence, searchPosition);
if ((emptyStartIndex != searchPosition) &&
(startIndex == -1 || endIndex == -1 ||
startIndex != searchPosition || endIndex < searchPosition + 2))
{
throw new Exception("ClusterToListOfStringGroups(), Invalid string input was given.");
}
if (emptyStartIndex == searchPosition)
{
int afterEmptyIndex = emptyStartIndex + emptyGroup.Length;
int length = afterEmptyIndex - emptyStartIndex;
result.Add(Use.SafeSubString(groupCluster, emptyStartIndex, length));
searchPosition = afterEmptyIndex;
}
else
{
int afterEndIndex = endIndex + endSequence.Length;
int length = afterEndIndex - startIndex;
result.Add(Use.SafeSubString(groupCluster, startIndex, length));
searchPosition = afterEndIndex;
}
}
return result;
}
static public void Test()
{
// Test the separating and grouping abilities.
string currentGroup = "{:1:2:3:}";
List<long> longList = StringGroup.GroupToList<long>(currentGroup);
List<int> intList = StringGroup.GroupToList<int>(currentGroup);
currentGroup = "{:abc77:3::}";
List<string> stringList1 = StringGroup.GroupToList<string>(currentGroup);
List<string> groupList = new List<string>();
currentGroup = StringGroup.GroupFromList(longList);
groupList.Add(currentGroup);
currentGroup = StringGroup.GroupFromList(new List<int>());
groupList.Add(currentGroup);
currentGroup = StringGroup.GroupFromList(intList);
groupList.Add(currentGroup);
currentGroup = StringGroup.GroupFromList(stringList1);
groupList.Add(currentGroup);
// Test the clustering abilities.
string cluster = StringGroup.ClusterFromListOfGroups(groupList);
List<string> groupList2 = StringGroup.ClusterToListOfGroups(cluster);
foreach (string stringGroup in groupList2)
{
List<string> stringList2 = StringGroup.GroupToList<string>(stringGroup);
}
}
}
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels