The StringUtils.chop method assumes the String to be chopped will only
contain EOL that are given by the line.separator property.  This can be
wrong in many circumstances.  The way I read the current implementation,
if the String contains \n and the line separator is \r\n, an extra
character will be chopped.  If the String contains \r\n and the line
separator is \n, the EOL will be considered 2 separate characters.  The
current method is also inefficient for chopping several characters as
well.

Here is a patch that provides a method for applications that can assume
the String and system line separators are the same.  As well as a method
that allows the application to specify the EOL.

John McNally

(if the patch is accepted or considered, I will be happy to regenerate
diff after dlr's changes.)



Index: src/java/org/apache/velocity/util/StringUtils.java
===================================================================
RCS file:
/home/cvspublic/jakarta-velocity/src/java/org/apache/velocity/util/StringUtils.java,v
retrieving revision 1.11
diff -u -r1.11 StringUtils.java
--- src/java/org/apache/velocity/util/StringUtils.java  2001/05/02
00:06:31        1.11
+++ src/java/org/apache/velocity/util/StringUtils.java  2001/05/03
00:42:17
@@ -173,8 +173,8 @@
 
     /**
      * Chop i characters off the end of a string.
-     * This method is sensitive to the EOL for a
-     * particular platform. The EOL character will
+     * This method assumes that any EOL characters in String s 
+     * and the platform EOL will be the same. The EOL character will
      * considered a single character.
      *
      * @param string String to chop.
@@ -183,15 +183,51 @@
      */
     public static String chop(String s, int i)
     {
-        for (int j = 0; j < i; j++)
+        return chop(s, i, EOL);
+    }
+
+    /**
+     * Chop i characters off the end of a string. The EOL character 
+     * will be considered a single character.  Assumes EOL 
+     * will be a 1 or 2 character string.
+     *
+     * @param string String to chop.
+     * @param i Number of characters to chop.
+     * @return String with processed answer.
+     */
+    public static String chop(String s, int i, String eol)
+    {        
+        char[] sa = s.toCharArray();
+        int length = sa.length;
+
+        switch ( eol.length() ) 
         {
-            if (EOL.indexOf(s.substring(s.length() - 1)) > 0 &&
EOL_LENGTH == 2)
-                s = s.substring(0, s.length() - 2);
-            else
-                s = s.substring(0, s.length() - 1);
-        }            
-    
-        return s;
+            case 1:
+                length -= i;
+                break;
+
+            case 2:       
+                char eol1 = eol.charAt(0);
+                char eol2 = eol.charAt(1);
+                for (int j = i-1; j >= 0; j--)
+                {
+                    if ( sa[length-1] == eol2 && sa[length-2] == eol1 ) 
+                    {
+                        length -= 2;
+                    }
+                    else 
+                    {
+                        length--;
+                    }
+                }
+                break;
+          
+            default:
+                throw new UnsupportedOperationException
+                    (eol + " is not a valid end of line marker.");
+        }
+
+        return new String(sa, 0, length);
     }
     
     /**

Reply via email to