Skip to content

cs2j enters an infinite loop when processing this class #33

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);
           }
       }

   }

}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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