Skip to content

cs2j enters an infinite loop when processing this class #33

@BlakeTNC

Description

@BlakeTNC

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 = "&#58;";
       /// <summary>


       /// leftBraceEscape
       /// Contains the left brace escape string used by this class.
       /// </summary>


       static private string leftBraceEscape = "&#123;";
       /// <summary>


       /// rightBraceEscape
       /// Contains the right brace escape string used by this class.
       /// </summary>


       static private string rightBraceEscape = "&#125;";
       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);
           }
       }

   }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions