Updated Branches:
  refs/heads/master b9c5c8614 -> 5b6e64552

o Simpler encoding of sysout/syserr byte array from fork to fork client


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/5b6e6455
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/5b6e6455
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/5b6e6455

Branch: refs/heads/master
Commit: 5b6e64552ccb750c561476358bdd384965f93db0
Parents: b9c5c86
Author: Andreas Gudian <agud...@apache.org>
Authored: Sun Jul 28 22:05:17 2013 +0200
Committer: Andreas Gudian <agud...@apache.org>
Committed: Sun Jul 28 22:05:17 2013 +0200

----------------------------------------------------------------------
 .../booterclient/output/ForkClient.java         |  12 +-
 .../surefire/booter/ForkingRunListener.java     |   6 +-
 .../surefire/util/internal/StringUtils.java     | 540 ++++---------------
 .../surefire/util/internal/StringUtilsTest.java |  42 +-
 4 files changed, 136 insertions(+), 464 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5b6e6455/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
index fa2f41d..3ed4110 100644
--- 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
+++ 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
@@ -44,7 +44,7 @@ import org.apache.maven.surefire.util.internal.StringUtils;
 
 /**
  * Knows how to reconstruct *all* the state transmitted over stdout by the 
forked process.
- * 
+ *
  * @author Kristian Rosenvold
  */
 public class ForkClient
@@ -135,13 +135,13 @@ public class ForkClient
                     }
                     break;
                 case ForkingRunListener.BOOTERCODE_STDOUT:
-                    byte[] bytes = new byte[remaining.length() * 2];
-                    int len = StringUtils.unescapeJava( bytes, remaining );
+                    byte[] bytes = new byte[remaining.length()];
+                    int len = StringUtils.unescapeBytes( bytes, remaining );
                     getOrCreateConsoleOutputReceiver( channelNumber 
).writeTestOutput( bytes, 0, len, true );
                     break;
                 case ForkingRunListener.BOOTERCODE_STDERR:
-                    bytes = new byte[remaining.length() * 2];
-                    len = StringUtils.unescapeJava( bytes, remaining );
+                    bytes = new byte[remaining.length()];
+                    len = StringUtils.unescapeBytes( bytes, remaining );
                     getOrCreateConsoleOutputReceiver( channelNumber 
).writeTestOutput( bytes, 0, len, false );
                     break;
                 case ForkingRunListener.BOOTERCODE_CONSOLE:
@@ -242,7 +242,7 @@ public class ForkClient
 
     /**
      * Used when getting reporters on the plugin side of a fork.
-     * 
+     *
      * @param channelNumber The logical channel number
      * @return A mock provider reporter
      */

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5b6e6455/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
----------------------------------------------------------------------
diff --git 
a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
 
b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
index 9a8beec..e515fd8 100644
--- 
a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
+++ 
b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
@@ -169,8 +169,8 @@ public class ForkingRunListener
     {
         byte[] header = stdout ? stdOutHeader : stdErrHeader;
         byte[] content =
-            new byte[buf.length * 6 + 1]; // Unicode escapes can be up to 6 
times length of regular char. Yuck.
-        int i = StringUtils.escapeJavaStyleString( content, 0, buf, off, len );
+            new byte[buf.length * 3 + 1]; // Hex-escaping can be up to 3 times 
length of a regular byte.
+        int i = StringUtils.escapeBytesToPrintable( content, 0, buf, off, len 
);
         content[i++] = (byte) '\n';
 
         synchronized ( target ) // See notes about synhronization/thread 
safety in class javadoc
@@ -219,7 +219,7 @@ public class ForkingRunListener
         byteBuffer.append( testSetChannelId );
         byteBuffer.comma();
         final int i =
-            StringUtils.escapeJavaStyleString( byteBuffer.getData(), 
byteBuffer.getlength(), buf, 0, buf.length );
+            StringUtils.escapeBytesToPrintable( byteBuffer.getData(), 
byteBuffer.getlength(), buf, 0, buf.length );
         byteBuffer.advance( i );
         byteBuffer.append( '\n' );
         synchronized ( target )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5b6e6455/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java
----------------------------------------------------------------------
diff --git 
a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java
 
b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java
index 4591f7a..99d087d 100644
--- 
a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java
+++ 
b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java
@@ -20,18 +20,20 @@ package org.apache.maven.surefire.util.internal;
  */
 
 import java.io.IOException;
-import java.io.PrintStream;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.util.StringTokenizer;
+
 import org.apache.maven.surefire.util.NestedRuntimeException;
 
 /**
- * <p>Common <code>String</code> manipulation routines.</p>
+ * <p>
+ * Common <code>String</code> manipulation routines.
+ * </p>
  * <p/>
- * <p>Originally from
- * <a href="http://jakarta.apache.org/turbine/";>Turbine</a> and the
- * GenerationJavaCore library.</p>
+ * <p>
+ * Originally from <a href="http://jakarta.apache.org/turbine/";>Turbine</a> 
and the GenerationJavaCore library.
+ * </p>
  *
  * @author <a href="mailto:j...@latchkey.com";>Jon S. Stevens</a>
  * @author <a href="mailto:d...@finemaltcoding.com";>Daniel Rall</a>
@@ -46,18 +48,19 @@ import 
org.apache.maven.surefire.util.NestedRuntimeException;
  * @author <a href="mailto:vincent.sive...@gmail.com";>Vincent Siveton</a>
  * @version $Id: StringUtils.java 8001 2009-01-03 13:17:09Z vsiveton $
  * @noinspection JavaDoc
- * <p/>
- * A quick borrow from plexus-utils by Kristian Rosenvold, to restore jdk1.3 
compat
- * Threw away all the unused stuff.
- * <p/>
- * NOTE: This class is not part of any api and is public purely for technical 
reasons !
+ *               <p/>
+ *               A quick borrow from plexus-utils by Kristian Rosenvold, to 
restore jdk1.3 compat Threw away all the
+ *               unused stuff.
+ *               <p/>
+ *               NOTE: This class is not part of any api and is public purely 
for technical reasons !
  * @since 1.0
  */
 public class StringUtils
 {
+    private static final byte[] HEX_CHARS = new byte[] {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        'A', 'B', 'C', 'D', 'E', 'F' };
 
-    // Splitting
-    
//--------------------------------------------------------------------------
 
     public static String[] split( String text, String separator )
     {
@@ -107,20 +110,19 @@ public class StringUtils
         return list;
     }
 
-
     /**
-     * <p>Checks if a (trimmed) String is <code>null</code> or blank.</p>
+     * <p>
+     * Checks if a (trimmed) String is <code>null</code> or blank.
+     * </p>
      *
      * @param str the String to check
-     * @return <code>true</code> if the String is <code>null</code>, or
-     *         length zero once trimmed
+     * @return <code>true</code> if the String is <code>null</code>, or length 
zero once trimmed
      */
     public static boolean isBlank( String str )
     {
         return ( ( str == null ) || ( str.trim().length() == 0 ) );
     }
 
-
     // Ripped from commons-lang StringEscapeUtils. Maybe Use dependency instead
     public static void unescapeJava( StringWriter out, String str )
     {
@@ -220,113 +222,39 @@ public class StringUtils
         }
     }
 
-    // Ripped from commons-lang StringEscapeUtils. Maybe Use dependency instead
-    public static int unescapeJava( byte[] out, String str )
+
+
+    // Ripped from commons-lang StringEscapeUtils. With a minor modification, 
we unicode-quote commas
+    // to avoid csv decoding problems ;)
+
+    /**
+     * Courtesy of commons-lang StringEscapeUtils, slightly modified, see below
+     *
+     * @param str String to escape values in, may be null
+     * @return the escaped string
+     */
+    public static void escapeJavaStyleString( StringBuffer target, String str )
     {
-        int outPos = 0;
-        if ( out == null )
-        {
-            throw new IllegalArgumentException( "The Writer must not be null" 
);
-        }
         if ( str == null )
         {
-            return 0;
+            return;
         }
-        int sz = str.length();
-        StringBuffer unicode = new StringBuffer( 4 );
-        boolean hadSlash = false;
-        boolean inUnicode = false;
-        for ( int i = 0; i < sz; i++ )
+        try
         {
-            char ch = str.charAt( i );
-            if ( inUnicode )
-            {
-                // if in unicode, then we're reading unicode
-                // values in somehow
-                unicode.append( ch );
-                if ( unicode.length() == 4 )
-                {
-                    // unicode now contains the four hex digits
-                    // which represents our unicode character
-                    try
-                    {
-                        int value = Integer.parseInt( unicode.toString(), 16 );
-                        out[outPos++] = (byte) value;
-                        unicode.setLength( 0 );
-                        inUnicode = false;
-                        hadSlash = false;
-                    }
-                    catch ( NumberFormatException nfe )
-                    {
-                        throw new NestedRuntimeException( "Unable to parse 
unicode value: " + unicode, nfe );
-                    }
-                }
-                continue;
-            }
-            if ( hadSlash )
-            {
-                // handle an escaped value
-                hadSlash = false;
-                switch ( ch )
-                {
-                    case '\\':
-                        out[outPos++] = '\\';
-                        break;
-                    case '\'':
-                        out[outPos++] = '\'';
-                        break;
-                    case '\"':
-                        out[outPos++] = '"';
-                        break;
-                    case 'r':
-                        out[outPos++] = '\r';
-                        break;
-                    case 'f':
-                        out[outPos++] = '\f';
-                        break;
-                    case 't':
-                        out[outPos++] = '\t';
-                        break;
-                    case 'n':
-                        out[outPos++] = '\n';
-                        break;
-                    case 'b':
-                        out[outPos++] = '\b';
-                        break;
-                    case 'u':
-                    {
-                        // uh-oh, we're in unicode country....
-                        inUnicode = true;
-                        break;
-                    }
-                    default:
-                        out[outPos++] = (byte) ch;
-                        break;
-                }
-                continue;
-            }
-            else if ( ch == '\\' )
-            {
-                hadSlash = true;
-                continue;
-            }
-            out[outPos++] = (byte) ch;
+            StringWriter writer = new StringWriter( str.length() * 2 );
+            escapeJavaStyleString( writer, str, true );
+            target.append( writer.toString() ); // todo: be bit smarter
         }
-        if ( hadSlash )
+        catch ( IOException ioe )
         {
-            // then we're in the weird case of a \ at the end of the
-            // string, let's output it anyway.
-            out[outPos++] = '\\';
+            // this should never ever happen while writing to a StringWriter
+            ioe.printStackTrace();
         }
-        return outPos;
     }
 
-    // Ripped from commons-lang StringEscapeUtils. With a minor modification, 
we unicode-quote commas
-    // to avoid csv decoding problems ;)
-
     /**
-     * @param out               write to receieve the escaped string
-     * @param str               String to escape values in, may be null
+     * @param out write to receieve the escaped string
+     * @param str String to escape values in, may be null
      * @param escapeSingleQuote escapes single quotes if <code>true</code>
      * @throws java.io.IOException if an IOException occurs
      */
@@ -357,7 +285,7 @@ public class StringUtils
                 out.write( "\\u0" + hex( ch ) );
             }
             else if ( ch > 0x7f || ch == ',' )
-            {    // Kr - this line modified from commons
+            { // Kr - this line modified from commons
                 out.write( "\\u00" + hex( ch ) );
             }
             else if ( ch < 32 )
@@ -427,202 +355,36 @@ public class StringUtils
         }
     }
 
-    public static void escapeJavaStyleString( ByteBuffer out, byte[] str, int 
off, int len )
-    {
-        if ( out == null )
-        {
-            throw new IllegalArgumentException( "The Writer must not be null" 
);
-        }
-        final int inputLength = str.length;
-        if ( str == null || inputLength == 0 )
-        {
-            return;
-        }
-        int outputPos = 0;
-        int end = off + len;
-        for ( int i = off; i < end; i++ )
-        {
-            char ch = (char) str[i];
 
-            // handle unicode
-            if ( ch > 0xfff )
-            {
-                outputPos = writeOut( out, outputPos, "\\u" + hex( ch ) );
-            }
-            else if ( ch > 0xff )
-            {
-                outputPos = writeOut( out, outputPos, "\\u0" + hex( ch ) );
-            }
-            else if ( ch > 0x7f || ch == ',' )
-            {    // Kr - this line modified from commons
-                outputPos = writeOut( out, outputPos, "\\u00" + hex( ch ) );
-            }
-            else if ( ch < 32 )
-            {
-                switch ( ch )
-                {
-                    case '\b':
-                        out.append( '\\' );
-                        out.append( 'b' );
-                        break;
-                    case '\n':
-                        out.append( '\\' );
-                        out.append( 'n' );
-                        break;
-                    case '\t':
-                        out.append( '\\' );
-                        out.append( 't' );
-                        break;
-                    case '\f':
-                        out.append( '\\' );
-                        out.append( 'f' );
-                        break;
-                    case '\r':
-                        out.append( '\\' );
-                        out.append( 'r' );
-                        break;
-                    default:
-                        if ( ch > 0xf )
-                        {
-                            outputPos = writeOut( out, outputPos, "\\u00" + 
hex( ch ) );
-                        }
-                        else
-                        {
-                            outputPos = writeOut( out, outputPos, "\\u000" + 
hex( ch ) );
-                        }
-                        break;
-                }
-            }
-            else
-            {
-                switch ( ch )
-                {
-                    case '\'':
-                        out.append( '\\' );
-                        out.append( '\'' );
-                        break;
-                    case '"':
-                        out.append( '\\' );
-                        out.append( '"' );
-                        break;
-                    case '\\':
-                        out.append( '\\' );
-                        out.append( '\\' );
-                        break;
-                    case '/':
-                        out.append( '\\' );
-                        out.append( '/' );
-                        break;
-                    default:
-                        out.append( ch );
-                        break;
-                }
-            }
-        }
-    }
-
-    public static void escapeJavaStyleString( PrintStream out, byte[] str, int 
off, int len )
+    public static String hex( char ch )
     {
-        if ( out == null )
-        {
-            throw new IllegalArgumentException( "The Writer must not be null" 
);
-        }
-        final int inputLength = str.length;
-        if ( str == null || inputLength == 0 )
-        {
-            return;
-        }
-        int outputPos = 0;
-        int end = off + len;
-        for ( int i = off; i < end; i++ )
-        {
-            char ch = (char) str[i];
-
-            // handle unicode
-            if ( ch > 0xfff )
-            {
-                outputPos = writeOut( out, outputPos, "\\u" + hex( ch ) );
-            }
-            else if ( ch > 0xff )
-            {
-                outputPos = writeOut( out, outputPos, "\\u0" + hex( ch ) );
-            }
-            else if ( ch > 0x7f || ch == ',' )
-            {    // Kr - this line modified from commons
-                outputPos = writeOut( out, outputPos, "\\u00" + hex( ch ) );
-            }
-            else if ( ch < 32 )
-            {
-                switch ( ch )
-                {
-                    case '\b':
-                        out.append( '\\' );
-                        out.append( 'b' );
-                        break;
-                    case '\n':
-                        out.append( '\\' );
-                        out.append( 'n' );
-                        break;
-                    case '\t':
-                        out.append( '\\' );
-                        out.append( 't' );
-                        break;
-                    case '\f':
-                        out.append( '\\' );
-                        out.append( 'f' );
-                        break;
-                    case '\r':
-                        out.append( '\\' );
-                        out.append( 'r' );
-                        break;
-                    default:
-                        if ( ch > 0xf )
-                        {
-                            outputPos = writeOut( out, outputPos, "\\u00" + 
hex( ch ) );
-                        }
-                        else
-                        {
-                            outputPos = writeOut( out, outputPos, "\\u000" + 
hex( ch ) );
-                        }
-                        break;
-                }
-            }
-            else
-            {
-                switch ( ch )
-                {
-                    case '\'':
-                        out.append( '\\' );
-                        out.append( '\'' );
-                        break;
-                    case '"':
-                        out.append( '\\' );
-                        out.append( '"' );
-                        break;
-                    case '\\':
-                        out.append( '\\' );
-                        out.append( '\\' );
-                        break;
-                    case '/':
-                        out.append( '\\' );
-                        out.append( '/' );
-                        break;
-                    default:
-                        out.append( ch );
-                        break;
-                }
-            }
-        }
+        return Integer.toHexString( ch ).toUpperCase();
     }
 
-    public static int escapeJavaStyleString( byte[] out, int outoff, byte[] 
str, int off, int len )
+
+    /**
+     * Escapes the bytes in the array {@code str} to contain only 'printable' 
bytes.
+     * <p>
+     * Escaping is done by encoding the non-nicely printable bytes to {@code 
'\' + upperCaseHexBytes(byte)}.
+     * <p>
+     * A save length of {@code out} is {@code len * 3 + outoff}.
+     * <p>
+     * The reverse-method is {@link #unescapeBytes(byte[], String)}.
+     *
+     * @param out output buffer
+     * @param outoff offset in the output buffer
+     * @param input input buffer
+     * @param off offset in the input buffer
+     * @param len number of bytes to copy from the input buffer
+     * @return number of bytes written to {@code out}
+     */
+    public static int escapeBytesToPrintable( byte[] out, int outoff, byte[] 
input, int off, int len )
     {
         if ( out == null )
         {
-            throw new IllegalArgumentException( "The Writer must not be null" 
);
+            throw new IllegalArgumentException( "The output array must not be 
null" );
         }
-        final int inputLength = str.length;
-        if ( str == null || inputLength == 0 )
+        if ( input == null || input.length == 0 )
         {
             return 0;
         }
@@ -630,165 +392,69 @@ public class StringUtils
         int end = off + len;
         for ( int i = off; i < end; i++ )
         {
-            char ch = (char) str[i];
+            byte b = input[i];
 
-            // handle unicode
-            if ( ch > 0xfff )
+            // handle non-nicely printable bytes
+            if ( b < 32 || b > 126 || b == '\\' )
             {
-                outputPos = writeOut( out, outputPos, "\\u" + hex( ch ) );
-            }
-            else if ( ch > 0xff )
-            {
-                outputPos = writeOut( out, outputPos, "\\u0" + hex( ch ) );
-            }
-            else if ( ch > 0x7f || ch == ',' )
-            {    // Kr - this line modified from commons
-                outputPos = writeOut( out, outputPos, "\\u00" + hex( ch ) );
-            }
-            else if ( ch < 32 )
-            {
-                switch ( ch )
-                {
-                    case '\b':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = 'b';
-                        break;
-                    case '\n':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = 'n';
-                        break;
-                    case '\t':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = 't';
-                        break;
-                    case '\f':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = 'f';
-                        break;
-                    case '\r':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = 'r';
-                        break;
-                    default:
-                        if ( ch > 0xf )
-                        {
-                            outputPos = writeOut( out, outputPos, "\\u00" + 
hex( ch ) );
-                        }
-                        else
-                        {
-                            outputPos = writeOut( out, outputPos, "\\u000" + 
hex( ch ) );
-                        }
-                        break;
-                }
+                int upper = ( 0xF0 & b ) >> 4;
+                int lower = ( 0x0F & b );
+                out[outputPos++] = '\\';
+                out[outputPos++] = HEX_CHARS[upper];
+                out[outputPos++] = HEX_CHARS[lower];
             }
             else
             {
-                switch ( ch )
-                {
-                    case '\'':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = '\'';
-                        break;
-                    case '"':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = '"';
-                        break;
-                    case '\\':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = '\\';
-                        break;
-                    case '/':
-                        out[outputPos++] = '\\';
-                        out[outputPos++] = '/';
-                        break;
-                    default:
-                        out[outputPos++] = (byte) ch;
-                        break;
-                }
+                out[outputPos++] = b;
             }
         }
-        return outputPos - outoff;
-    }
-
-    private static int writeOut( ByteBuffer out, int outputPos, final String 
msg )
-    {
-        byte[] bytes = msg.getBytes();
-        for ( int cnt = 0; cnt < bytes.length; cnt++ )
-        {
-            out.append( bytes[cnt] );
-        }
-        return outputPos;
-    }
 
-    private static int writeOut( PrintStream out, int outputPos, final String 
msg )
-    {
-        byte[] bytes = msg.getBytes();
-        for ( int cnt = 0; cnt < bytes.length; cnt++ )
-        {
-            out.write( bytes[cnt] );
-        }
-        return outputPos;
-    }
-
-
-    private static int writeOut( byte[] out, int outputPos, final String msg )
-    {
-        byte[] bytes = msg.getBytes();
-        for ( int cnt = 0; cnt < bytes.length; cnt++ )
-        {
-            out[outputPos++] = bytes[cnt];
-        }
-        return outputPos;
+        return outputPos - outoff;
     }
 
 
-    public static String hex( char ch )
-    {
-        return Integer.toHexString( ch ).toUpperCase();
-    }
-
     /**
-     * Courtesy of commons-lang StringEscapeUtils, slightly modified, see below
+     * Reverses the effect of {@link #escapeBytesToPrintable(byte[], int, 
byte[], int, int)}.
+     * <p>
+     * A save length of {@code out} is {@code str.length()}
      *
-     * @param str String to escape values in, may be null
-     * @return the escaped string
+     * @param out the target byte array
+     * @param str the input String
+     * @return the number of bytes written to {@code out}
      */
-    public static void escapeJavaStyleString( StringBuffer target, String str )
+    public static int unescapeBytes( byte[] out, String str )
     {
-        if ( str == null )
+        int outPos = 0;
+        if ( out == null )
         {
-            return;
+            throw new IllegalArgumentException( "The output array must not be 
null" );
         }
-        try
+        if ( str == null )
         {
-            StringWriter writer = new StringWriter( str.length() * 2 );
-            escapeJavaStyleString( writer, str, true );
-            target.append( writer.toString() ); // todo: be bit smarter
+            return 0;
         }
-        catch ( IOException ioe )
+        for ( int i = 0; i < str.length(); i++ )
         {
-            // this should never ever happen while writing to a StringWriter
-            ioe.printStackTrace();
+            char ch = str.charAt( i );
+
+            if (ch == '\\') {
+                int upper = fromHex( str.charAt( ++i ));
+                int lower = fromHex( str.charAt( ++i ));
+                out[outPos++] = (byte) (upper << 4 | lower);
+            }
+            else {
+                out[outPos++] = (byte) ch;
+            }
         }
+        return outPos;
     }
 
-    public static void escapeJavaStyleString( PrintStream target, String str )
+    private static int fromHex( char c )
     {
-        if ( str == null )
-        {
-            return;
-        }
-        try
-        {
-            StringWriter writer = new StringWriter( str.length() * 2 );
-            escapeJavaStyleString( writer, str, true );
-            target.append( writer.toString() ); // todo: be bit smarter
-        }
-        catch ( IOException ioe )
-        {
-            // this should never ever happen while writing to a StringWriter
-            ioe.printStackTrace();
+        if ( c <= '9' ) {
+            return c - '0';
+        } else{
+            return (c - 'A') + 10;
         }
     }
 }
-

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/5b6e6455/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
 
b/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
index de3bf02..61012af 100644
--- 
a/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
+++ 
b/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
@@ -19,6 +19,8 @@ package org.apache.maven.surefire.util.internal;
  * under the License.
  */
 
+import java.util.Arrays;
+
 import junit.framework.TestCase;
 
 /**
@@ -30,26 +32,30 @@ public class StringUtilsTest
 
     public void testUnescape()
     {
-        byte[] buffer = new byte[80];
-        final int abc = StringUtils.unescapeJava( buffer, "ABC" );
-        assertEquals( 3, abc );
-    }
+        byte[] input = new byte[256];
 
-    public void testUnescapeWithEscape()
-    {
-        byte[] buffer = new byte[80];
-        final int abc = StringUtils.unescapeJava( buffer, "AB\tC" );
-        assertEquals( 4, abc );
-    }
+        for ( int i = 0; i <= 0xFF; i++ )
+        {
+            byte b = (byte) ( 0xFF & i );
+            input[i] = b;
+        }
 
-    public void testEscape()
-    {
-        ByteBuffer buffer = new ByteBuffer( 80 );
-        StringUtils.escapeJavaStyleString( buffer, "AB\tC".getBytes(), 0, 4 );
-        assertEquals( 5, buffer.getlength() );
-        String temp = buffer.toString();
-        assertEquals( "AB\\tC", temp );
+        byte[] escaped = new byte[input.length * 3];
 
-    }
+        int escapedBytes = StringUtils.escapeBytesToPrintable( escaped, 0, 
input, 0, input.length );
 
+        String escapedString = new String( escaped, 0, escapedBytes );
+        System.out.println( escapedString );
+
+        assertEquals( escapedBytes, escapedString.length() );
+
+        byte[] unescaped = new byte[input.length];
+        int unescapeBytes = StringUtils.unescapeBytes( unescaped, 
escapedString );
+
+        assertEquals( input.length, unescapeBytes );
+
+        for (int i = 0; i < input.length; i++) {
+            assertEquals("At position " + i, input[i], unescaped[i]);
+        }
+    }
 }

Reply via email to