You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2009/08/01 06:15:09 UTC

svn commit: r799800 - in /commons/proper/codec/trunk/src: java/org/apache/commons/codec/binary/Base64.java java/org/apache/commons/codec/binary/StringUtils.java test/org/apache/commons/codec/binary/Base64Test.java

Author: ggregory
Date: Sat Aug  1 04:15:09 2009
New Revision: 799800

URL: http://svn.apache.org/viewvc?rev=799800&view=rev
Log:
[CODEC-59] Add methods to Base64 which work with String instead of byte[]. Patch applied with one added test code line to keep line code coverage at 100%. Branch coverage up to 92% from 91%.

Modified:
    commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java
    commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/StringUtils.java
    commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java

Modified: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java?rev=799800&r1=799799&r2=799800&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java (original)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64.java Sat Aug  1 04:15:09 2009
@@ -540,7 +540,7 @@
             }
             byte b = in[inPos++];
             if (b == PAD) {
-                // WE'RE DONE!!!!
+                // We're done.
                 eof = true;
                 break;
             } else {
@@ -628,19 +628,30 @@
      * 
      * @param binaryData
      *            binary data to encode
-     * @return Base64 characters
+     * @return byte[] containing Base64 characters in their UTF-8 representation.
      */
     public static byte[] encodeBase64(byte[] binaryData) {
         return encodeBase64(binaryData, false);
     }
 
     /**
+     * Encodes binary data using the base64 algorithm into 76 character blocks separated by CRLF.
+     *
+     * @param binaryData
+     *            binary data to encode
+     * @return String containing Base64 characters.
+     */    
+    public static String encodeBase64String(byte[] binaryData) {
+        return StringUtils.newStringUtf8(encodeBase64(binaryData, true));
+    }
+    
+    /**
      * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
      * url-safe variation emits - and _ instead of + and / characters.
      * 
      * @param binaryData
      *            binary data to encode
-     * @return Base64 characters
+     * @return byte[] containing Base64 characters in their UTF-8 representation.
      * @since 1.4
      */
     public static byte[] encodeBase64URLSafe(byte[] binaryData) {
@@ -648,6 +659,19 @@
     }
 
     /**
+     * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
+     * url-safe variation emits - and _ instead of + and / characters.
+     *
+     * @param binaryData
+     *            binary data to encode
+     * @return String containing Base64 characters
+     * @since 1.4
+     */    
+    public static String encodeBase64URLSafeString(byte[] binaryData) {
+        return StringUtils.newStringUtf8(encodeBase64(binaryData, false, true));
+    }    
+
+    /**
      * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks
      * 
      * @param binaryData
@@ -660,23 +684,36 @@
 
     /**
      * Decodes an Object using the base64 algorithm. This method is provided in order to satisfy the requirements of the
-     * Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[].
+     * Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String.
      * 
      * @param pObject
      *            Object to decode
-     * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] supplied.
+     * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String supplied.
      * @throws DecoderException
      *             if the parameter supplied is not of type byte[]
      */
-    public Object decode(Object pObject) throws DecoderException {
+    public Object decode(Object pObject) throws DecoderException {        
         if (pObject instanceof byte[]) {
             return decode((byte[]) pObject);
+        } else if (pObject instanceof String) {
+            return decode((String) pObject);
         } else {
-            throw new DecoderException("Parameter supplied to Base64 decode is not a byte[]");
+            throw new DecoderException("Parameter supplied to Base64 decode is not a byte[] or a String");
         }
     }
 
     /**
+     * Decodes a String containing containing characters in the Base64 alphabet.
+     *
+     * @param pArray
+     *            A String containing Base64 character data
+     * @return a byte array containing binary data
+     */
+    public byte[] decode(String pArray) {
+        return decode(StringUtils.getBytesUtf8(pArray));
+    }
+
+    /**
      * Decodes a byte[] containing containing characters in the Base64 alphabet.
      * 
      * @param pArray
@@ -684,6 +721,7 @@
      * @return a byte array containing binary data
      */
     public byte[] decode(byte[] pArray) {
+        reset();
         if (pArray == null || pArray.length == 0) {
             return pArray;
         }
@@ -771,6 +809,17 @@
     }
 
     /**
+     * Decodes a Base64 String into octets
+     *
+     * @param base64String
+     *            String containing Base64 data
+     * @return Array containing decoded data.
+     */
+    public static byte[] decodeBase64(String base64String) {
+        return new Base64().decode(base64String);
+    }
+
+    /**
      * Decodes Base64 data into octets
      * 
      * @param base64Data
@@ -778,8 +827,7 @@
      * @return Array containing decoded data.
      */
     public static byte[] decodeBase64(byte[] base64Data) {
-        Base64 b64 = new Base64();
-        return b64.decode(base64Data);
+        return new Base64().decode(base64Data);
     }
 
     /**
@@ -848,6 +896,17 @@
     }
 
     /**
+     * Encodes a byte[] containing binary data, into a String containing characters in the Base64 alphabet.
+     *
+     * @param pArray
+     *            a byte array containing binary data
+     * @return A String containing only Base64 character data
+     */    
+    public String encodeToString(byte[] pArray) {
+        return StringUtils.newStringUtf8(encode(pArray));
+    }
+
+    /**
      * Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64 alphabet.
      * 
      * @param pArray
@@ -855,6 +914,10 @@
      * @return A byte array containing only Base64 character data
      */
     public byte[] encode(byte[] pArray) {
+        reset();        
+        if (pArray == null || pArray.length == 0) {
+            return pArray;
+        }
         long len = getEncodeLength(pArray, lineLength, lineSeparator);
         byte[] buf = new byte[(int) len];
         setInitialBuffer(buf, 0, buf.length);
@@ -964,4 +1027,17 @@
         System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len);
         return resizedBytes;
     }
+
+    /**
+     * Resets this Base64 object to its initial newly constructed state.
+     */
+    private void reset() {
+        buffer = null;
+        pos = 0;
+        readPos = 0;
+        currentLinePos = 0;
+        modulus = 0;
+        eof = false;
+    }
+
 }

Modified: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/StringUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/StringUtils.java?rev=799800&r1=799799&r2=799800&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/StringUtils.java (original)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/StringUtils.java Sat Aug  1 04:15:09 2009
@@ -149,6 +149,9 @@
      * @see String#getBytes(String)
      */
     public static byte[] getSupportedBytes(String string, String charsetName) {
+        if (string == null) {
+            return null;
+        }
         try {
             return string.getBytes(charsetName);
         } catch (UnsupportedEncodingException e) {
@@ -179,6 +182,9 @@
      * @see String#String(byte[], String)
      */
     public static String newString(byte[] bytes, String charsetName) {
+        if (bytes == null) {
+            return null;
+        }
         try {
             return new String(bytes, charsetName);
         } catch (UnsupportedEncodingException e) {

Modified: commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java?rev=799800&r1=799799&r2=799800&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java (original)
+++ commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64Test.java Sat Aug  1 04:15:09 2009
@@ -60,7 +60,8 @@
     public void testBase64() {
         String content = "Hello World";
         String encodedContent;
-        encodedContent = new String(Base64.encodeBase64(content.getBytes()));
+        byte[] encodedBytes = Base64.encodeBase64(StringUtils.getBytesUtf8(content));
+        encodedContent = StringUtils.newStringUtf8(encodedBytes);
         assertTrue("encoding hello world", encodedContent.equals("SGVsbG8gV29ybGQ="));
     }
 
@@ -288,7 +289,7 @@
         empty = new byte[0];
         result = Base64.decodeBase64(empty);
         assertEquals("empty base64 decode", 0, result.length);
-        assertEquals("empty base64 encode", null, Base64.decodeBase64(null));
+        assertEquals("empty base64 encode", null, Base64.decodeBase64((byte[]) null));
     }
 
     // encode/decode a large random array
@@ -423,8 +424,8 @@
         Base64 b64 = new Base64();
 
         try {
-            b64.decode("Yadayadayada");
-            fail("decode(Object) didn't throw an exception when passed a String object");
+            b64.decode(new Integer(5));
+            fail("decode(Object) didn't throw an exception when passed an Integer object");
         } catch (DecoderException e) {
             // ignored
         }
@@ -956,6 +957,45 @@
         }
     }
 
+    public void testByteToStringVariations() throws DecoderException {
+        Base64 base64 = new Base64(0);
+        byte[] b1 = StringUtils.getBytesUtf8("Hello World");
+        byte[] b2 = new byte[0];
+        byte[] b3 = null;
+        byte[] b4 = Hex.decodeHex("2bf7cc2701fe4397b49ebeed5acc7090".toCharArray());  // for url-safe tests
+
+        assertEquals("byteToString Hello World", "SGVsbG8gV29ybGQ=", base64.encodeToString(b1));
+        assertEquals("byteToString static Hello World", "SGVsbG8gV29ybGQ=\r\n", Base64.encodeBase64String(b1));
+        assertEquals("byteToString \"\"", "", base64.encodeToString(b2));
+        assertEquals("byteToString static \"\"", "", Base64.encodeBase64String(b2));
+        assertEquals("byteToString null", null, base64.encodeToString(b3));
+        assertEquals("byteToString static null", null, Base64.encodeBase64String(b3));
+        assertEquals("byteToString UUID", "K/fMJwH+Q5e0nr7tWsxwkA==", base64.encodeToString(b4));
+        assertEquals("byteToString static UUID", "K/fMJwH+Q5e0nr7tWsxwkA==\r\n", Base64.encodeBase64String(b4));
+        assertEquals("byteToString static-url-safe UUID", "K_fMJwH-Q5e0nr7tWsxwkA", Base64.encodeBase64URLSafeString(b4));
+    }
+
+    public void testStringToByteVariations() throws DecoderException {
+        Base64 base64 = new Base64();
+        String s1 = "SGVsbG8gV29ybGQ=\r\n";
+        String s2 = "";
+        String s3 = null;
+        String s4a = "K/fMJwH+Q5e0nr7tWsxwkA==\r\n";
+        String s4b = "K_fMJwH-Q5e0nr7tWsxwkA";
+        byte[] b4 = Hex.decodeHex("2bf7cc2701fe4397b49ebeed5acc7090".toCharArray());  // for url-safe tests
+
+        assertEquals("StringToByte Hello World", "Hello World", StringUtils.newStringUtf8(base64.decode(s1)));
+        assertEquals("StringToByte Hello World", "Hello World", StringUtils.newStringUtf8((byte[])base64.decode((Object)s1)));
+        assertEquals("StringToByte static Hello World", "Hello World", StringUtils.newStringUtf8(Base64.decodeBase64(s1)));
+        assertEquals("StringToByte \"\"", "", StringUtils.newStringUtf8(base64.decode(s2)));
+        assertEquals("StringToByte static \"\"", "", StringUtils.newStringUtf8(Base64.decodeBase64(s2)));
+        assertEquals("StringToByte null", null, StringUtils.newStringUtf8(base64.decode(s3)));
+        assertEquals("StringToByte static null", null, StringUtils.newStringUtf8(Base64.decodeBase64(s3)));
+        assertTrue("StringToByte UUID", Arrays.equals(b4, base64.decode(s4b)));
+        assertTrue("StringToByte static UUID", Arrays.equals(b4, Base64.decodeBase64(s4a)));
+        assertTrue("StringToByte static-url-safe UUID", Arrays.equals(b4, Base64.decodeBase64(s4b)));
+    }
+
     private String toString(byte[] data) {
         StringBuffer buf = new StringBuffer();
         for (int i = 0; i < data.length; i++) {